This commit allows us to force the relocation of functions being
[dyninst.git] / dyninstAPI / src / inst-sparc-solaris.C
1 /*
2  * Copyright (c) 1996 Barton P. Miller
3  * 
4  * We provide the Paradyn Parallel Performance Tools (below
5  * described as Paradyn") on an AS IS basis, and do not warrant its
6  * validity or performance.  We reserve the right to update, modify,
7  * or discontinue this software at any time.  We shall have no
8  * obligation to supply such updates or modifications or any other
9  * form of support to you.
10  * 
11  * This license is for research uses.  For such uses, there is no
12  * charge. We define "research use" to mean you may freely use it
13  * inside your organization for whatever purposes you see fit. But you
14  * may not re-distribute Paradyn or parts of Paradyn, in any form
15  * source or binary (including derivatives), electronic or otherwise,
16  * to any other organization or entity without our permission.
17  * 
18  * (for other uses, please contact us at paradyn@cs.wisc.edu)
19  * 
20  * All warranties, including without limitation, any warranty of
21  * merchantability or fitness for a particular purpose, are hereby
22  * excluded.
23  * 
24  * By your use of Paradyn, you understand and agree that we (or any
25  * other person or entity with proprietary rights in Paradyn) are
26  * under no obligation to provide either maintenance services,
27  * update services, notices of latent defects, or correction of
28  * defects for Paradyn.
29  * 
30  * Even if advised of the possibility of such damages, under no
31  * circumstances shall we (or any other person or entity with
32  * proprietary rights in the software licensed hereunder) be liable
33  * to you or any third party for direct, indirect, or consequential
34  * damages of any character regardless of type of action, including,
35  * without limitation, loss of profits, loss of use, loss of good
36  * will, or computer failure or malfunction.  You agree to indemnify
37  * us (and any other person or entity with proprietary rights in the
38  * software licensed hereunder) for any and all liability it may
39  * incur to third parties resulting from your use of Paradyn.
40  */
41
42 // $Id: inst-sparc-solaris.C,v 1.87 2001/07/11 21:19:57 gurari Exp $
43
44 #include "dyninstAPI/src/inst-sparc.h"
45 #include "dyninstAPI/src/instPoint.h"
46 #include "common/h/debugOstream.h"
47
48 // Needed for function relocation
49 #include "dyninstAPI/src/func-reloc.h"
50
51 #include <sys/utsname.h>
52 #include <stdlib.h>
53
54 extern bool relocateFunction(process *proc, instPoint *&location);
55 extern bool branchInsideRange(instruction insn, Address branchAddress, 
56                               Address firstAddress, Address lastAddress); 
57 extern instPoint* find_overlap(vector<instPoint*> v, Address targetAddress);
58 extern void sorted_ips_vector(vector<instPoint*>&fill_in);
59
60 /****************************************************************************/
61 /****************************************************************************/
62 /****************************************************************************/
63
64 // static unsigned pfdp_to_pfdp_hash(pd_Function * const &f) {
65 //     pd_Function *pdf = f;
66 //     unsigned l = (unsigned)pdf;
67 //     return addrHash4(l); 
68 // }
69
70 /****************************************************************************/
71 /****************************************************************************/
72 /****************************************************************************/
73
74 // Another constructor for the class instPoint. This one is called
75 // for the define the instPoints for regular functions which means
76 // multiple instructions is going to be moved to based trampoline.
77 // Since we will use the instruction CALL to branch to the base
78 // tramp(so it doesn't have any code size restriction), things are
79 // a little more complicated because instruction CALL changes the 
80 // value in the link register.
81 instPoint::instPoint(pd_Function *f, const instruction &instr, 
82                      const image *owner, Address &adr,
83                      bool delayOK,
84                      instPointType pointType)
85 : insnAddr(adr), addr(adr), originalInstruction(instr), 
86   inDelaySlot(false), isDelayed(false),
87   callIndirect(false), callAggregate(false), callee(NULL), 
88   func(f),
89   ipType(pointType), image_ptr(owner), firstIsConditional(false),
90   relocated_(false), isLongJump(false)
91 {
92
93   isBranchOut = false;
94   size = 0;
95
96   // When the function has a stack frame
97   if (!this->hasNoStackFrame()) {
98
99       // we will treat the first instruction after the SAVE instruction
100       // in the nonleaf procedure as the function entry.  
101       if (ipType == functionEntry) {
102
103           assert(isInsnType(instr, SAVEmask, SAVEmatch));
104           saveInsn.raw = owner->get_instruction(addr);
105           addr += 4;
106           originalInstruction.raw = owner->get_instruction(addr);
107           delaySlotInsn.raw = owner->get_instruction(addr+4);
108           size += 2*sizeof(instruction);
109
110           // If the second instruction is DCTI, we need to move the
111           // the instruction in the delayed slot.
112           if (IS_DELAYED_INST(delaySlotInsn)) {
113               isDelayed = true; 
114               isDelayedInsn.raw = owner->get_instruction(addr+8);
115               size += 1*sizeof(instruction);
116
117               // Life is Hard. If the second instruction is actually
118               // an CALL instruction, we need to move the instruction
119               // after the instruction in the delayed slot if the 
120               // return value of this function is a aggregate value.
121               aggregateInsn.raw = owner->get_instruction(addr+12);
122               if (isCallInsn(delaySlotInsn)) {
123                   if (!IS_VALID_INSN(aggregateInsn) && aggregateInsn.raw != 0) {
124                       callAggregate = true;
125                       size += 1*sizeof(instruction);
126                   }
127               }
128           }
129
130       // The following are easier.        
131       } else if (ipType == callSite) {
132           delaySlotInsn.raw = owner->get_instruction(addr+4);
133           size += 2*sizeof(instruction);
134
135           aggregateInsn.raw = owner->get_instruction(addr+8);
136           if (!IS_VALID_INSN(aggregateInsn) && aggregateInsn.raw != 0) {
137               callAggregate = true;
138               size += 1*sizeof(instruction);
139           }
140       } else {
141           delaySlotInsn.raw = owner->get_instruction(addr+4);
142           size += 2*sizeof(instruction);
143       }
144   }
145
146   // When the function is a leaf function
147   else {
148
149       // For the leaf procedure, there are no function calls in
150       // this procdure. So we don't need to consider the 
151       // aggregate instuction.
152       if (ipType == functionEntry) {
153
154           otherInstruction.raw = owner->get_instruction(addr+4);
155           delaySlotInsn.raw = owner->get_instruction(addr+8);
156           size += 2*sizeof(instruction);
157
158           if (IS_DELAYED_INST(delaySlotInsn)) {
159               isDelayed = true;
160               isDelayedInsn.raw = owner->get_instruction(addr+12);
161               size += 2*sizeof(instruction);
162           }
163
164       } else if (ipType == functionExit) {
165           
166           addr -= 4;
167
168           if (owner->isValidAddress(addr-4)) {
169               instruction iplus1;
170               iplus1.raw = owner->get_instruction(addr-4);
171               if (IS_DELAYED_INST(iplus1) && !delayOK) {
172                   addr -= 4;
173                   inDelaySlot = true;
174                   size += 1*sizeof(instruction);
175                   if(isCondBranch(iplus1)){
176                       instruction previous_inst; 
177                       previous_inst.raw = owner->get_instruction(addr-4);
178                       firstIsConditional = true;
179                       addr -= sizeof(instruction);
180                       size += 1*sizeof(instruction);
181                   }
182               }
183           }
184
185           originalInstruction.raw = owner->get_instruction(addr);
186           otherInstruction.raw = owner->get_instruction(addr+4);
187           delaySlotInsn.raw = owner->get_instruction(addr+8);
188           size += 3*sizeof(instruction);
189
190           if (inDelaySlot) {
191               inDelaySlotInsn.raw = owner->get_instruction(addr+12);
192               if(firstIsConditional) {
193                   extraInsn.raw = owner->get_instruction(addr+16);
194               }
195           }
196       } else if(ipType == otherPoint) {
197           delaySlotInsn.raw = owner->get_instruction(addr+4);
198           size += 2*sizeof(instruction);
199       } else {
200           assert(ipType == callSite);
201           // Usually, a function without a stack frame won't have any call sites
202           //cerr << "inst-sparc-solaris.C WARNING: found a leaf fn (no stack frame)" 
203           //     << "which makes a function call : " << func->prettyName()
204           //     << " at address " << adr << endl;
205           //abort();
206           // Actually - that is incorrect.  It confuses a leaf function
207           //  (one without a stack frame of its own) with a function which
208           //  does not make any calls).  It is possible for a function without
209           //  a stack frae to make calls in the case of e.g. tail-call 
210           //  optimization (in this case, the function could end with
211           //  e.g. jmp, nop)....
212           delaySlotInsn.raw = owner->get_instruction(addr+4);
213           size += 2*sizeof(instruction);
214
215           aggregateInsn.raw = owner->get_instruction(addr+8);
216           if (!IS_VALID_INSN(aggregateInsn) && aggregateInsn.raw != 0) {
217               callAggregate = true;
218               size += 1*sizeof(instruction);
219           }
220       }
221   }
222
223   // return the address in the code segment after this instruction
224   // sequence. (there's a -1 here because one will be added up later in
225   // the function findInstPoints)  
226   adr = addr + (size - 1*sizeof(instruction));
227 }
228
229 /****************************************************************************/
230 /****************************************************************************/
231 /****************************************************************************/
232
233 // return the instruction after originalInstruction....
234 const instruction instPoint::insnAfterPoint() const {
235     if (this->hasNoStackFrame()) {
236       switch (ipType) {
237       case functionEntry: 
238         return otherInstruction;
239         break;
240       case callSite:
241         return delaySlotInsn;
242         break;
243       case functionExit:
244         return otherInstruction;
245         break;
246       default:
247         assert(false);
248       }
249     } else {
250       switch (ipType) {
251       case functionEntry:
252         return delaySlotInsn;
253         break;
254       case callSite:
255         return delaySlotInsn;
256         break;
257       case functionExit:
258         return delaySlotInsn;
259       default:
260         assert(false);
261       }
262     }
263
264     // should never be reached....
265     assert(false);
266     // prevent warning about lack of return value....
267     return delaySlotInsn;
268 }
269
270 /****************************************************************************/
271 /****************************************************************************/
272 /****************************************************************************/
273
274 void AstNode::sysFlag(instPoint *location)
275 {
276     if (location -> ipType == functionEntry) {
277         astFlag = (location -> isLongJump)? false:true; 
278     } else if (location -> ipType == functionExit) {
279        astFlag = location -> hasNoStackFrame(); // formerly "isLeaf()"
280     } else
281         astFlag = false;
282
283     if (loperand)
284         loperand->sysFlag(location);
285     if (roperand)
286         roperand->sysFlag(location); 
287
288     for (unsigned u = 0; u < operands.size(); u++) {
289         operands[u]->sysFlag(location);
290     }
291 }
292
293 /****************************************************************************/
294 /****************************************************************************/
295 /****************************************************************************/
296
297 // Determine if the called function is a "library" function or a "user" function
298 // This cannot be done until all of the functions have been seen, verified, and
299 // classified
300 //
301 void pd_Function::checkCallPoints() {
302   instPoint *p;
303   Address loc_addr;
304
305   //cerr << "pd_Function:: checkCallPoints called, *this = " << *this;
306
307   vector<instPoint*> non_lib;
308
309   for (unsigned i=0; i<calls.size(); ++i) {
310     /* check to see where we are calling */
311     p = calls[i];
312     assert(p);
313
314     if (isInsnType(p->originalInstruction, CALLmask, CALLmatch)) {
315       //cerr << " isIsinType TRUE" << endl;
316       // Direct call
317       loc_addr = p->addr + (p->originalInstruction.call.disp30 << 2);
318       pd_Function *pdf = (file_->exec())->findFunction(loc_addr);
319       if (pdf) {
320         p->callee = pdf;
321         non_lib.push_back(p);
322         //cerr << "  pdf (called func?) non-NULL = " << *pdf;
323       } else if(!pdf){
324            //cerr << "  pdf (called func) NULL" << endl;
325            // if this is a call outside the fuction, keep it
326            if((loc_addr < getAddress(0))||(loc_addr > (getAddress(0)+size()))){
327                 //cerr << "   apparent call outside function, adding p to non_lib"
328                 //     << endl;
329                 p->callIndirect = true;
330                 p->callee = NULL; 
331                 non_lib.push_back(p);
332            }
333            else {
334                //cerr << "   apparent call inside function, deleting p" << endl;
335                delete p;
336            }
337       } 
338     } else {
339       //cerr << " isIsinType FALSE, assuming call to unnamed user function" << endl;
340       // Indirect call -- be conservative, assume it is a call to 
341       // an unnamed user function
342       assert(!p->callee); assert(p->callIndirect);
343       p->callee = NULL;
344       non_lib.push_back(p);
345     }
346   }
347   calls = non_lib;
348 }
349
350 /****************************************************************************/
351 /****************************************************************************/
352 /****************************************************************************/
353
354 // TODO we cannot find the called function by address at this point in time
355 // because the called function may not have been seen.
356 // reloc_info is 0 if the function is not currently being relocated
357 // Note that this may be called even when instr is NOT a CAlL inst, e.g.
358 //  in the case of a jmp instruction where paradynd/dyninstAPI knows
359 //  (really guesses) that control flow will return to the point following
360 //  the jmp, or wants
361 //  to mark the jmp as a call to preserve its logical structure of 
362 //  synchronous call + return (which is violated by tail-call optimization -
363 //  including a function (w/o stack frame) which ends w/ jmp, nop....
364 Address pd_Function::newCallPoint(Address &adr, const instruction instr,
365                                  const image *owner, bool &err, 
366                                  unsigned &callId, Address &oldAddr,
367                                  relocatedFuncInfo *reloc_info,
368                                  const instPoint *&location)
369 {
370     Address ret=adr;
371     instPoint *point;
372  
373 #ifdef DEBUG_CALL_POINTS
374     cerr << "pd_Function::newCallPoint called " << endl;
375     cerr << " this " << *this << endl;
376     cerr << " adr = " << adr << endl;
377     cerr << " isTrap = " << isTrap << endl;
378     cerr << " reloc_info = " << reloc_info << endl;
379 #endif
380
381     err = true;
382     
383     if (isTrap) {
384         point = new instPoint(this, instr, owner, adr, false, callSite, oldAddr);
385     } else {
386         point = new instPoint(this, instr, owner, adr, false, callSite);
387     }
388     //point = new instPoint(this, instr, owner, adr, false, callSite);
389
390     if (!isInsnType(instr, CALLmask, CALLmatch)) {
391       point->callIndirect = true;
392       point->callee = NULL;
393     } else{
394       point->callIndirect = false;
395     }
396
397     if (isTrap) {
398         if (!reloc_info) {
399             calls.push_back(point);
400             calls[callId] -> instId = callId; callId++;
401         } else {
402             // calls to a location within the function are not
403             // kept in the calls vector
404
405 #ifdef DEBUG_CALL_POINTS
406             cerr << " *this = " << *this;
407             cerr << " callId = " << callId;
408             cerr << " (u_int)callId = " << (u_int)callId;
409             cerr << " calls.size() = " << calls.size() << endl;
410             cerr << " calls = " << endl;
411             for(unsigned un=0;un<calls.size();un++) {
412                 cerr << calls[un] << " , ";
413             }
414             cerr << endl;
415 #endif
416
417             point->relocated_ = true;
418
419             // Alert!!!!
420             // cannot simply assert that this is true, because of the case
421             //  where (as a hack), the call site in a tail-call optimization
422             //  might not have been previously seen....
423             assert((callId) < calls.size());
424           
425             if(location && (calls[callId] == location)) { 
426                 assert(calls[callId]->instId  == location->instId);
427                 location = point; 
428             } 
429            
430             point->instId = callId++;
431             reloc_info->addFuncCall(point);
432         }
433     } else {
434         if (!reloc_info) {
435             calls.push_back(point);
436         }
437         else {
438             point->relocated_ = true;
439             reloc_info->addFuncCall(point);
440         }
441     }
442     err = false;
443     return ret;
444 }
445
446 /****************************************************************************/
447 /****************************************************************************/
448 /****************************************************************************/
449
450 /*
451  * Given an instruction, relocate it to a new address, patching up
452  *   any relative addressing that is present.
453  * 
454  */
455 void relocateInstruction(instruction*& insn, 
456                         Address origAddr, Address& targetAddr, process *proc)
457 {
458     int newOffset;
459
460     // If the instruction is a CALL instruction, calculate the new
461     // offset
462     if (isInsnType(*insn, CALLmask, CALLmatch)) {
463     
464       newOffset = origAddr  - targetAddr + (insn->call.disp30 << 2);
465       insn->call.disp30 = newOffset >> 2;
466     
467     } else if (isInsnType(*insn, BRNCHmask, BRNCHmatch)||
468                isInsnType(*insn, FBRNCHmask, FBRNCHmatch)) {
469
470         // If the instruction is a Branch instruction, calculate the 
471         // new offset. If the new offset is out of reach after the 
472         // instruction is moved to the base Trampoline, we would do
473         // the following:
474         //    b  address  ......    address: save
475         //                                   call new_offset             
476         //                                   restore 
477         newOffset = origAddr - targetAddr + (insn->branch.disp22 << 2);
478
479         // if the branch is too far, then allocate more space in inferior
480         // heap for a call instruction to branch target.  The base tramp 
481         // will branch to this new inferior heap code, which will call the
482         // target of the branch
483         if (!offsetWithinRangeOfBranchInsn(newOffset)) {
484 //      if (ABS(newOffset) > getMaxBranch1Insn()) {
485             int ret = inferiorMalloc(proc,3*sizeof(instruction), textHeap,targetAddr);
486             assert(ret);
487             u_int old_offset = insn->branch.disp22 << 2;
488             insn->branch.disp22  = (ret - targetAddr)>>2;
489             instruction insnPlus[3];
490             genImmInsn(insnPlus, SAVEop3, REG_SPTR, -112, REG_SPTR);
491             generateCallInsn(insnPlus+1, ret+sizeof(instruction), 
492                              origAddr+old_offset);
493             genSimpleInsn(insnPlus+2, RESTOREop3, 0, 0, 0); 
494             proc->writeDataSpace((caddr_t)ret, sizeof(insnPlus), 
495                          (caddr_t) insnPlus);
496         } else {
497             insn->branch.disp22 = newOffset >> 2;
498         }
499     } else if (isInsnType(*insn, TRAPmask, TRAPmatch)) {
500         // There should be no probelm for moving trap instruction
501         // logLine("attempt to relocate trap\n");
502     } 
503     /* The rest of the instructions should be fine as is */
504 }
505
506 /****************************************************************************/
507 /****************************************************************************/
508 /****************************************************************************/
509
510 void generate_base_tramp_recursive_guard_code( process & p,
511                                                instruction * code,
512                                                Address base_addr,
513                                                NonRecursiveTrampTemplate & templ )
514 {
515   /* prepare guard flag memory, if needed */
516   Address guard_flag_address = p.getTrampGuardFlagAddr();
517   if( guard_flag_address == 0 )
518     {
519         int initial_value = 1;
520         guard_flag_address = inferiorMalloc( & p, sizeof( int ), dataHeap );
521         /* initialize the new value */
522         p.writeDataSpace( ( void * )guard_flag_address, sizeof( int ), & initial_value );
523
524         p.setTrampGuardFlagAddr( guard_flag_address );
525     }
526
527   instruction * curr_instr;
528   Address curr_addr;
529
530   /* fill the 'guard on' pre-instruction instrumentation */
531   curr_instr = code + templ.guardOnPre_beginOffset / sizeof( instruction );
532   curr_addr = base_addr + templ.guardOnPre_beginOffset;
533   generateSetHi( curr_instr, guard_flag_address, REG_L(0) );
534   curr_instr++; curr_addr += sizeof( instruction );
535   genSimpleInsn( curr_instr, ADDop3, REG_G(0), REG_G(0), REG_L(1) );
536   curr_instr++; curr_addr += sizeof( instruction );
537   generateLoad( curr_instr, REG_L(0), LOW10( guard_flag_address ), REG_L(2) );
538   curr_instr++; curr_addr += sizeof( instruction );
539   generateStore( curr_instr, REG_L(1), REG_L(0), LOW10( guard_flag_address ) );
540   curr_instr++; curr_addr += sizeof( instruction );
541   genSimpleInsn( curr_instr, SUBop3cc, REG_L(2), REG_G(0), REG_G(0) );
542   curr_instr++; curr_addr += sizeof( instruction );
543   int branch_offset_in_bytes =
544     ( base_addr + templ.guardOffPre_endOffset )
545     -
546     curr_addr
547     ;
548   genBranch( curr_instr,
549              branch_offset_in_bytes,
550              BEcond,
551              false );
552   curr_instr++; curr_addr += sizeof( instruction );
553   generateNOOP ( curr_instr );
554
555   /* fill the 'guard off' pre-instruction instrumentation */
556   curr_instr = code + templ.guardOffPre_beginOffset / sizeof( instruction );
557   curr_addr = base_addr + templ.guardOffPre_beginOffset;
558   generateSetHi( curr_instr, guard_flag_address, REG_L(0) );
559   curr_instr++; curr_addr += sizeof( instruction );
560   genImmInsn( curr_instr, ADDop3, REG_G(0), 1, REG_L(1) );
561   curr_instr++; curr_addr += sizeof( instruction );
562   generateStore( curr_instr, REG_L(1), REG_L(0), LOW10( guard_flag_address ) );
563
564   /* fill the 'guard on' post-instruction instrumentation */
565   curr_instr = code + templ.guardOnPost_beginOffset / sizeof( instruction );
566   curr_addr = base_addr + templ.guardOnPost_beginOffset;
567   generateSetHi( curr_instr, guard_flag_address, REG_L(0) );
568   curr_instr++; curr_addr += sizeof( instruction );
569   genSimpleInsn( curr_instr, ADDop3, REG_G(0), REG_G(0), REG_L(1) );
570   curr_instr++; curr_addr += sizeof( instruction );
571   generateLoad( curr_instr, REG_L(0), LOW10( guard_flag_address ), REG_L(2) );
572   curr_instr++; curr_addr += sizeof( instruction );
573   generateStore( curr_instr, REG_L(1), REG_L(0), LOW10( guard_flag_address ) );
574   curr_instr++; curr_addr += sizeof( instruction );
575   genSimpleInsn( curr_instr, SUBop3cc, REG_L(2), REG_G(0), REG_G(0) );
576   curr_instr++; curr_addr += sizeof( instruction );
577   branch_offset_in_bytes =
578     ( base_addr + templ.guardOffPost_endOffset )
579     -
580     curr_addr
581     ;
582   genBranch( curr_instr,
583              branch_offset_in_bytes,
584              BEcond,
585              false );
586   curr_instr++; curr_addr += sizeof( instruction );
587   generateNOOP ( curr_instr );
588
589   /* fill the 'guard off' post-instruction instrumentation */
590   curr_instr = code + templ.guardOffPost_beginOffset / sizeof( instruction );
591   curr_addr = base_addr + templ.guardOffPost_beginOffset;
592   generateSetHi( curr_instr, guard_flag_address, REG_L(0) );
593   curr_instr++; curr_addr += sizeof( instruction );
594   genImmInsn( curr_instr, ADDop3, REG_G(0), 1, REG_L(1) );
595   curr_instr++; curr_addr += sizeof( instruction );
596   generateStore( curr_instr, REG_L(1), REG_L(0), LOW10( guard_flag_address ) );
597 }
598
599 /****************************************************************************/
600 /****************************************************************************/
601 /****************************************************************************/
602
603 /*
604  * Install a base tramp -- fill calls with nop's for now.
605  *
606  * This one install the base tramp for the regular functions.
607  *
608  */
609 trampTemplate * installBaseTramp( instPoint * & location,
610                                   process * proc,
611                                   bool trampRecursiveDesired = false )
612 {
613   trampTemplate*  current_template = &nonRecursiveBaseTemplate;
614
615   if(location->ipType == otherPoint)
616         current_template = &nonRecursiveConservativeBaseTemplate;
617
618   if( trampRecursiveDesired )
619     {
620       current_template = &baseTemplate;
621
622       if(location->ipType == otherPoint)
623                 current_template = &conservativeBaseTemplate;
624     }
625
626     Address ipAddr = 0;
627     proc->getBaseAddress( location->image_ptr, ipAddr );
628     ipAddr += location->addr;
629
630     Address baseAddr = inferiorMalloc( proc, current_template->size, textHeap, ipAddr );
631     assert( baseAddr );
632
633     /* very conservative installation as o7 can be live at 
634       this arbitrary inst point */
635     if((location->ipType == otherPoint) && 
636        (in1BranchInsnRange(ipAddr, baseAddr) == false))
637     {
638         vector<addrVecType> pointsToCheck;
639         inferiorFree(proc,baseAddr,pointsToCheck);
640         return NULL;
641     }
642
643     instruction * code = new instruction[ current_template->size ];
644     assert( code );
645
646     memcpy( ( char * )code,
647             ( char * )current_template->trampTemp,
648             current_template->size );
649
650     instruction * temp;
651     Address currAddr;
652     for (temp = code, currAddr = baseAddr; 
653         (currAddr - baseAddr) < (unsigned) current_template->size;
654         temp++, currAddr += sizeof(instruction)) {
655
656         if (temp->raw == EMULATE_INSN) {
657
658             // Load the value of link register from stack 
659             // If no stack frame, genereate a RESTORE instruction
660             // since there's an instruction SAVE generated and put in the
661             // code segment.
662             if (location -> hasNoStackFrame()) {
663
664                 Address baseAddress = 0;
665                 proc->getBaseAddress(location->image_ptr,baseAddress);
666                 baseAddress += location -> addr;
667
668                 if (in1BranchInsnRange(baseAddress, baseAddr) == false) {
669                     //cerr << "This happen very rarely, I suppose "<< endl;
670                     //cerr << "Lets see if this is going to be executed..." << endl;
671                     location -> isLongJump = true;
672                     genImmInsn(temp, RESTOREop3, 0, 0, 0);
673                 } else {
674                     generateNOOP(temp);
675                 }
676                 temp++;
677                 currAddr += sizeof(instruction);
678             } 
679             // Same for the leaf and nonleaf functions.
680             // First, relocate the "FIRST instruction" in the sequence;  
681             Address fromAddr = location->addr;
682
683             if (!(location -> hasNoStackFrame())) {
684                 if (location -> ipType == functionEntry) {
685                     *temp = location -> saveInsn;
686                     temp++;
687                     currAddr += sizeof(instruction);
688                 }
689             }
690             *temp = location->originalInstruction;
691
692             // compute the real from address if this instrumentation
693             // point is from a shared object image
694             Address baseAddress = 0;
695             if(proc->getBaseAddress(location->image_ptr,baseAddress)){
696                 fromAddr += baseAddress;                
697             }
698
699             // If the instruction is a call instruction to a location somewhere 
700             // within the function, then the 07 regester must be saved and 
701             // resored around the relocated call from the base tramp...the call
702             // instruction changes the value of 07 to be the PC value, and if
703             // we move the call instruction to the base tramp, its value will
704             // be incorrect when we use it in the function.  We generate the
705             // following base tramp code:
706             //          original delay slot instruction 
707             //          save
708             //          original call instruction
709             //          restore
710             // This case should only occur for function entry points in
711             // functions from shared objects, and there should be no append
712             // trampolene code because the relocated call instruction will
713             // not return to the base tramp
714             if (isInsnType(*temp, CALLmask, CALLmatch)) {
715                 Address offset = fromAddr + (temp->call.disp30 << 2);
716                 if ((offset > (location->func->getAddress(0)+ baseAddress)) && 
717                     (offset < ((location->func->getAddress(0)+ baseAddress)+
718                                  location->func->size()))) {
719                     // offset > adr; "=" means recursive function which is allowed
720                     // offset < adr + size; "=" does not apply to this case
721
722                     // TODO: this assumes that the delay slot instruction is not
723                     // a call instruction....is this okay?
724                     
725                     // assume this situation only happens at function entry point 
726                     // for the shared library routine. And it is definately nees
727                     // long jump support
728                     assert(location -> ipType == functionEntry); 
729                     location -> isLongJump = true;
730                     
731                     // In this situation, save instruction is discarded
732                     // Rollback!! 
733                     assert(location->hasNoStackFrame() == false);
734                     temp--;
735                     currAddr -= sizeof(instruction);
736                     
737                     *temp = location->delaySlotInsn;  
738                     temp++; 
739                     currAddr += sizeof(instruction);
740                     genImmInsn(temp, SAVEop3, REG_SPTR, -112, REG_SPTR); 
741                     temp++; 
742                     currAddr += sizeof(instruction);  
743                     *temp = location->originalInstruction;
744                     relocateInstruction(temp,fromAddr,currAddr,(process *)proc);
745                     temp++; 
746                     fromAddr += sizeof(instruction); 
747                     currAddr += sizeof(instruction);
748                     genImmInsn(temp, RESTOREop3, 0, 0, 0);
749                     continue;
750                 }
751             }   
752
753             relocateInstruction(temp,fromAddr,currAddr,(process *)proc);
754
755             // Again, for leaf function, one more is needed to move for one
756             // more spot;
757             if (location->hasNoStackFrame()) {
758                 // check to see if the otherInstruction is a call instruction
759                 // to itself, if so then generate the following
760                 // before               after           basetramp
761                 // ------               -----           ---------
762                 // mov   originalInsn   mov             sethi
763                 // call  otherInsn      call            save
764                 // sethi delaySlot      nop             call
765                 //                                      restore
766                 // the idea is to not really relocate the originalInsn, and
767                 // relocate only the call otherInsn and delaySlot instrn
768                 // then do a save and restore around the relocated call to
769                 // save the value of the o7 register from the call to base tramp
770                 if (isInsnType(location->otherInstruction,CALLmask,CALLmatch)) {
771                   *temp = location->otherInstruction;
772                   fromAddr += sizeof(instruction);
773                   Address offset = fromAddr + (temp->call.disp30 << 2);
774                   if ((offset > (location->func->getAddress(0)+baseAddress)) && 
775                     (offset < ((location->func->getAddress(0)+ baseAddress)+
776                                  location->func->size()))) {
777                        location -> isLongJump = true;
778                        // need to replace retore instr with nop 
779                        temp--;
780                        generateNOOP(temp);
781                        // relocate delaySlot instr
782                        temp++;
783                        *temp = location->delaySlotInsn;
784                        fromAddr += sizeof(instruction);
785                        relocateInstruction(temp,fromAddr,currAddr, 
786                                           (process *)proc);
787                        temp++; 
788                        currAddr += sizeof(instruction);
789                        genImmInsn(temp, SAVEop3, REG_SPTR, -112, REG_SPTR); 
790
791                        // relocate the call instruction     
792                        temp++; 
793                        currAddr += sizeof(instruction);
794                        fromAddr -= sizeof(instruction);
795                        *temp = location->otherInstruction;
796                        relocateInstruction(temp,fromAddr,currAddr, 
797                                            (process *)proc);
798                        temp++; 
799                        fromAddr += sizeof(instruction); 
800                        currAddr += sizeof(instruction);
801                        genImmInsn(temp, RESTOREop3, 0, 0, 0);
802                        continue;
803                   }
804                 }
805
806                 // otherwise relocate the other instruction
807                 fromAddr += sizeof(instruction);
808                 currAddr += sizeof(instruction);
809                 *++temp = location->otherInstruction;
810                 relocateInstruction(temp, fromAddr, currAddr, 
811                                     (process *)proc);
812             }     
813             
814             // Second, relocate the "NEXT instruction";
815             fromAddr += sizeof(instruction);
816             currAddr += sizeof(instruction);
817             *++temp = location->delaySlotInsn;
818  
819             // if the NEXT instruction is a call instruction to a location
820             // within the function, then the 07 regester must be saved and 
821             // resored around the relocated call from the base tramp...the call
822             // instruction changes the value of 07 to be the PC value, and if
823             // we move the call instruction to the base tramp, its value will
824             // be incorrect when we use it in the function.  We generate:
825             //
826             //  orignial            relocated to base tramp
827             //  --------            -----------------------
828             //  save                nop  // SAVE added above, replace w/nop 
829             //  original insn       original instruction // already relocated
830             //  delaySlotInsn       isDelayedInsn
831             //  isDelayedInsn       save
832             //                      delaySlotInsn  (call with offset - 4)
833             //                      restore
834             //  In the function, the call to the base tramp will have an
835             //  additional add instruction to adjust the 07 register
836             //  orignial            relocated to base tramp
837             //  --------            -----------------------
838             //  save                 save       
839             //  mov                  call
840             //  call                 nop
841             //  sethi                add $o7 4   
842             //
843             if (isInsnType(*temp, CALLmask, CALLmatch)) {
844                 Address offset = fromAddr + (temp->call.disp30 << 2);
845                 if ((offset > (location->func->getAddress(0)+ baseAddress)) && 
846                     (offset < ((location->func->getAddress(0)+ baseAddress)+
847                                  location->func->size()))) {
848                     
849                     temp--;
850                     temp--;
851                     generateNOOP(temp);  
852                     temp++;
853                     temp++;
854                     location->isLongJump = true;
855                     // assert(location->hasNoStackFrame() == false);
856                     // assume that this is not a delayed instr.
857                     *temp = location->isDelayedInsn;  
858                     temp++; 
859                     currAddr += sizeof(instruction);
860                     genImmInsn(temp, SAVEop3, REG_SPTR, -112, REG_SPTR); 
861                     temp++; 
862                     currAddr += sizeof(instruction);  
863                     *temp = location->delaySlotInsn;
864                     Address new_call_addr = fromAddr - sizeof(instruction);
865                     relocateInstruction(temp,new_call_addr,currAddr,proc);
866                     temp++; 
867                     fromAddr += sizeof(instruction); 
868                     currAddr += sizeof(instruction);
869                     genImmInsn(temp, RESTOREop3, 0, 0, 0);
870                     continue;
871                 }
872             }   
873
874             // otherwise relocate the NEXT instruction
875             relocateInstruction(temp, fromAddr, currAddr,
876                                 (process *)proc);
877             
878             // Third, if the "NEXT instruction" is a DCTI, 
879             if (location->isDelayed) {
880                 fromAddr += sizeof(instruction);
881                 currAddr += sizeof(instruction);
882                 *++temp = location->isDelayedInsn;
883                 relocateInstruction(temp, fromAddr, currAddr,
884                                     (process *)proc);
885                 
886                 // Then, possibly, there's an callAggregate instruction
887                 // after this. 
888                 if (location->callAggregate) {
889                     currAddr += sizeof(instruction);
890                     *++temp = location->aggregateInsn;
891                     continue;
892                 }       
893             }
894             
895             // If the "FIRST instruction" is a DCTI, then our so called 
896             // "NEXT instruction" is in the delayed Slot and this might
897             // happen. (actullay, it happened)
898             if (location->callAggregate) {
899                 currAddr += sizeof(instruction);
900                 *++temp = location->aggregateInsn;
901                 continue;
902             }   
903             
904             // For the leaf function, if there's an inDelaySlot instruction,
905             // move this one to the base Tramp.(i.e. at the function exit,
906             // if the first instruction is in the delayed slot the previous
907             // instruction, we have to move that one too, so we count from 
908             // that one and the last one is this sequence is called inDelaySlot
909             // instruction.)
910             // Well, after all these, another SAVE instruction is generated
911             // so we are prepared to handle the returning to our application's
912             // code segment. 
913             if (location->hasNoStackFrame()) {
914                 if (location->inDelaySlot) {
915                     fromAddr += sizeof(instruction);
916                     currAddr += sizeof(instruction);
917                     *++temp = location->inDelaySlotInsn;
918                     relocateInstruction(temp,fromAddr,currAddr,(process *)proc);
919                     if(location->firstIsConditional){
920                         fromAddr += sizeof(instruction);
921                         currAddr += sizeof(instruction);
922                         *++temp = location->extraInsn;
923                         relocateInstruction(temp, fromAddr, currAddr, proc);
924                     }
925                 } 
926                 
927                 genImmInsn(temp+1, SAVEop3, REG_SPTR, -112, REG_SPTR);
928             }
929             
930         } else if (temp->raw == RETURN_INSN) {
931             // compute the real from address if this instrumentation
932             // point is from a shared object image
933             Address baseAddress = 0;
934             if(proc->getBaseAddress(location->image_ptr,baseAddress)){
935             }
936             // Back to the code segement of the application.
937             // If the location is in the leaf procedure, generate an RESTORE
938             // instruction right after the CALL instruction to restore all
939             // the values in the registers.
940             if (location -> hasNoStackFrame()) {
941                 generateCallInsn(temp, currAddr, 
942                                 (baseAddress + location->addr)+location->size);
943                 genImmInsn(temp+1, RESTOREop3, 0, 0, 0);
944             } else if(location->ipType == otherPoint){
945                 /** to save the value of live o7 register we save and call*/
946                 genImmInsn(temp, SAVEop3, REG_SPTR, -120, REG_SPTR);
947                 generateCallInsn(temp+1, currAddr+sizeof(instruction), 
948                                 (baseAddress + location->addr)+location->size);
949                 genImmInsn(temp+2, RESTOREop3, 0, 0, 0);
950             } else {
951                 generateCallInsn(temp, currAddr, 
952                                 (baseAddress + location->addr)+location->size);
953             }
954         } else if (temp->raw == SKIP_PRE_INSN) {
955             unsigned offset;
956             offset = baseAddr+current_template->updateCostOffset-currAddr;
957             generateBranchInsn(temp,offset);
958         } else if (temp->raw == SKIP_POST_INSN) {
959
960             unsigned offset;
961             offset = baseAddr+current_template->returnInsOffset-currAddr;
962             generateBranchInsn(temp,offset);
963
964         } else if (temp->raw == UPDATE_COST_INSN) {         
965             current_template->costAddr = currAddr;
966             generateNOOP(temp);
967         } else if ((temp->raw == LOCAL_PRE_BRANCH) ||
968                    (temp->raw == GLOBAL_PRE_BRANCH) ||
969                    (temp->raw == LOCAL_POST_BRANCH) ||
970                    (temp->raw == GLOBAL_POST_BRANCH)) {
971 #if defined(MT_THREAD)
972             if ((temp->raw == LOCAL_PRE_BRANCH) ||
973                 (temp->raw == LOCAL_POST_BRANCH)) 
974             {
975               temp -= NUM_INSN_MT_PREAMBLE;
976               Address numIns=0;
977               generateMTpreamble((char *)temp, numIns, proc);
978               temp += NUM_INSN_MT_PREAMBLE;
979             }
980 #endif
981             /* fill with no-op */
982             generateNOOP(temp);
983         }
984         else if( temp->raw == RECURSIVE_GUARD_ON_PRE_INSN )
985           {
986             generateNOOP( temp );
987           }
988         else if( temp->raw == RECURSIVE_GUARD_OFF_PRE_INSN )
989           {
990             generateNOOP( temp );
991           }
992         else if( temp->raw == RECURSIVE_GUARD_ON_POST_INSN )
993           {
994             generateNOOP( temp );
995           }
996         else if( temp->raw == RECURSIVE_GUARD_OFF_POST_INSN )
997           {
998             generateNOOP( temp );
999           }
1000     }
1001
1002   if( ! trampRecursiveDesired )
1003     {
1004       generate_base_tramp_recursive_guard_code( * proc,
1005                                                 code,
1006                                                 baseAddr,
1007                                                 ( NonRecursiveTrampTemplate & )*current_template );
1008     }
1009
1010     // TODO cast
1011     proc->writeDataSpace( ( caddr_t )baseAddr,
1012                           current_template->size,
1013                           ( caddr_t )code );
1014     delete [] code;
1015
1016     trampTemplate * baseInst;
1017     if( trampRecursiveDesired )
1018       {
1019         baseInst = new trampTemplate;
1020       }
1021     else
1022       {
1023         baseInst = new NonRecursiveTrampTemplate;
1024       }
1025     * baseInst = *current_template;
1026     baseInst->baseAddr = baseAddr;
1027
1028     return baseInst;
1029 }
1030
1031 /****************************************************************************/
1032 /****************************************************************************/
1033 /****************************************************************************/
1034
1035 /*
1036  * Install the base Tramp for the function relocated.
1037  * (it means the base tramp that don't need to bother with long jump and
1038  *  is the one we used before for all the functions(since there's no
1039  *  long jumps)
1040  *  for system calls
1041  */ 
1042 trampTemplate *installBaseTrampSpecial(const instPoint *&location,
1043                                        process *proc, bool &deferred,
1044                                        bool trampRecursiveDesired = false)
1045 {
1046   trampTemplate* current_template = &nonRecursiveBaseTemplate;
1047
1048   if(location->ipType == otherPoint)
1049         current_template = &nonRecursiveConservativeBaseTemplate;
1050
1051   if( trampRecursiveDesired )
1052     {
1053       current_template = &baseTemplate;
1054
1055       if(location->ipType == otherPoint)
1056                 current_template = &conservativeBaseTemplate;
1057     }
1058
1059   Address currAddr;
1060   instruction *code;
1061   instruction *temp;
1062
1063   bool relocated;
1064
1065   if(!(location->func->isInstalled(proc))) {
1066     relocated = location->func->relocateFunction(proc, const_cast<instPoint *>(location), deferred);
1067
1068     // Unable to relocate function
1069     if (relocated == false) {
1070       return NULL;
1071     }
1072   }
1073   else if(!location->relocated_){
1074     // need to find new instPoint for location...it has the pre-relocated
1075     // address of the instPoint
1076     location->func->modifyInstPoint(location,proc);
1077   }
1078
1079   code = new instruction[current_template->size];
1080   memcpy((char *) code, (char*) current_template->trampTemp, current_template->size);
1081
1082   Address baseAddr = inferiorMalloc(proc, current_template->size, textHeap, location->addr);
1083   assert(baseAddr);
1084
1085   for (temp = code, currAddr = baseAddr; 
1086        (currAddr - baseAddr) < (unsigned) current_template->size;
1087        temp++, currAddr += sizeof(instruction)) {
1088
1089     if (temp->raw == EMULATE_INSN) {
1090       if (location->isBranchOut) {
1091                 // the original instruction is a branch that goes out of a 
1092                 // function.  We don't relocate the original instruction. We 
1093                 // only get to the tramp if the branch is taken, so we generate
1094                 // an unconditional branch to the target of the original 
1095                 // instruction here 
1096                 assert(location->branchTarget);
1097                 int disp = location->branchTarget - currAddr;
1098
1099                 if (in1BranchInsnRange(currAddr,location->branchTarget)) {
1100                   generateBranchInsn(temp, disp);
1101                   disp = temp->branch.disp22;
1102                 } else {
1103                   generateCallInsn(temp, currAddr, disp);
1104                 }
1105                 continue;
1106             }
1107             else {
1108                 *temp = location->originalInstruction;
1109                 Address fromAddress = location->addr;
1110                 relocateInstruction(temp, fromAddress, currAddr, proc);
1111                 if (location->isDelayed) {
1112                     /* copy delay slot instruction into tramp instance */
1113                     currAddr += sizeof(instruction);  
1114                     *++temp = location->delaySlotInsn;
1115                 }
1116                 if (location->callAggregate) {
1117                     /* copy invalid insn with aggregate size in it */
1118                     currAddr += sizeof(instruction);  
1119                     *++temp = location->aggregateInsn;
1120                 }
1121             }
1122         } else if (temp->raw == RETURN_INSN) {
1123             generateBranchInsn(temp, 
1124                 (location->addr+ sizeof(instruction) - currAddr));
1125             if (location->isDelayed) {
1126                 /* skip the delay slot instruction */
1127                 temp->branch.disp22 += 1;
1128             }
1129             if (location->callAggregate) {
1130                 /* skip the aggregate size slot */
1131                 temp->branch.disp22 += 1;
1132             }
1133         } else if (temp->raw == SKIP_PRE_INSN) {
1134           unsigned offset;
1135           offset = baseAddr+current_template->updateCostOffset-currAddr;
1136           generateBranchInsn(temp,offset);
1137         } else if (temp->raw == SKIP_POST_INSN) {
1138           unsigned offset;
1139           offset = baseAddr+current_template->returnInsOffset-currAddr;
1140           generateBranchInsn(temp,offset);
1141         } else if (temp->raw == UPDATE_COST_INSN) {         
1142
1143             current_template->costAddr = currAddr;
1144             generateNOOP(temp);
1145         } else if ((temp->raw == LOCAL_PRE_BRANCH) ||
1146                    (temp->raw == GLOBAL_PRE_BRANCH) ||
1147                    (temp->raw == LOCAL_POST_BRANCH) ||
1148                    (temp->raw == GLOBAL_POST_BRANCH)) {
1149 #if defined(MT_THREAD)
1150             if ((temp->raw == LOCAL_PRE_BRANCH) ||
1151                 (temp->raw == LOCAL_POST_BRANCH)) 
1152             {
1153               temp -= NUM_INSN_MT_PREAMBLE;
1154               Address numIns=0;
1155               generateMTpreamble((char *)temp, numIns, proc);
1156               temp += NUM_INSN_MT_PREAMBLE;
1157             }
1158 #endif
1159             /* fill with no-op */
1160             generateNOOP(temp);
1161         }
1162         else if( temp->raw == RECURSIVE_GUARD_ON_PRE_INSN )
1163           {
1164             generateNOOP( temp );
1165           }
1166         else if( temp->raw == RECURSIVE_GUARD_OFF_PRE_INSN )
1167           {
1168             generateNOOP( temp );
1169           }
1170         else if( temp->raw == RECURSIVE_GUARD_ON_POST_INSN )
1171           {
1172             generateNOOP( temp );
1173           }
1174         else if( temp->raw == RECURSIVE_GUARD_OFF_POST_INSN )
1175           {
1176             generateNOOP( temp );
1177           }
1178   }
1179
1180   if( ! trampRecursiveDesired )
1181     {
1182       generate_base_tramp_recursive_guard_code( * proc,
1183                                                 code,
1184                                                 baseAddr,
1185                                                 ( NonRecursiveTrampTemplate & )*current_template );
1186     }
1187
1188     // TODO cast
1189     proc->writeDataSpace((caddr_t)baseAddr, current_template->size,(caddr_t) code);
1190
1191     delete [] code;
1192
1193     trampTemplate * baseInst;
1194     if( trampRecursiveDesired )
1195       {
1196         baseInst = new trampTemplate;
1197       }
1198     else
1199       {
1200         baseInst = new NonRecursiveTrampTemplate;
1201       }
1202     * baseInst = *current_template;
1203     baseInst->baseAddr = baseAddr;
1204
1205     return baseInst;
1206 }
1207
1208 /****************************************************************************/
1209 /****************************************************************************/
1210 /****************************************************************************/
1211
1212 /*
1213  * Allocate the space for the base Trampoline, and generate the instruction
1214  * we need for modifying the code segment.
1215  *
1216  * 'retInstance' tells you how to modify the code to jump to the base tramp
1217  *
1218  */
1219 trampTemplate *findAndInstallBaseTramp(process *proc, 
1220                                        instPoint *&location,
1221                                        returnInstance *&retInstance,
1222                                        bool trampRecursionDesired,
1223                                        bool, 
1224                                        bool &deferred)
1225 {
1226     Address adr = location->addr;
1227     retInstance = NULL;
1228
1229     const instPoint *&cLocation = const_cast<const instPoint *&>(location);
1230  
1231     trampTemplate *ret;
1232     if (proc->baseMap.find(cLocation, ret)) // writes to ret if found
1233        // This base tramp already exists; nothing to do.
1234        return ret;
1235
1236     if (location->func->isTrapFunc()) {
1237        // get the base Address of this function if it is a 
1238        // shared object
1239        Address baseAddress = 0;
1240        if(!proc->getBaseAddress(location->image_ptr,baseAddress)){
1241           // TODO: what should be done here?    
1242           logLine("Error:findAndInstallBaseTramp call getBaseAddress\n"); 
1243        }
1244        // Install Base Tramp for the functions which are 
1245        // relocated to the heap.
1246        // vector<instruction> extra_instrs;  // not any more
1247
1248        ret = installBaseTrampSpecial(cLocation, proc, deferred, 
1249                                      trampRecursionDesired);
1250        if(!ret) return NULL;
1251
1252        // add a branch from relocated function to the base tramp
1253        // if function was just relocated then location has old address
1254        // otherwise location will have address in already relocated func
1255        if (!location->func->isInstalled(proc)){
1256           if (location->isBranchOut){
1257              changeBranch(proc, location->addr, 
1258                           (int) ret->baseAddr, location->originalInstruction);
1259            } else {
1260              generateBranch(proc, location->addr, (int)ret->baseAddr);
1261            }
1262        }
1263        else {  // location's address is correct...it is in the heap
1264           if (location->isBranchOut){
1265              changeBranch(proc, location->addr, 
1266                           (int) ret->baseAddr, location->originalInstruction);
1267           } else {
1268              generateBranch(proc, location->addr, (int)ret->baseAddr);
1269           }
1270        }
1271
1272        // If for this process, a call to the relocated function has not
1273        // yet be installed in its original location, then genterate either
1274        //   BA,A
1275        // or
1276        //   SAVE;             CALL;         RESTORE.
1277        // so that it would jump to the start of the relocated function
1278        // which is in heap.
1279        if (!location->func->isInstalled(proc)){
1280           location->func->setInstalled(proc);
1281
1282           Address adr = location-> func -> getAddress(0);
1283           instruction *insn;
1284           unsigned branchSize ;
1285           if (in1BranchInsnRange(adr+baseAddress, location->func->getAddress(proc))) {
1286             branchSize = 1 ;
1287             insn = new instruction[branchSize];
1288             generateBranchInsn(insn,(int)(location->func->getAddress(proc)-(adr+baseAddress)));
1289           } else {
1290             branchSize = 3 ;
1291             insn = new instruction[branchSize];
1292             genImmInsn(insn, SAVEop3, REG_SPTR, -112, REG_SPTR);
1293             generateCallInsn(insn+1, adr+baseAddress+4, location->func->getAddress(proc));
1294             genSimpleInsn(insn+2, RESTOREop3, 0, 0, 0);
1295           }
1296
1297           // set unknown the number of instructions to be overwritten 
1298           retInstance = new returnInstance(0/*branchSize*/, (instructUnion *)insn,
1299                                            branchSize*sizeof(instruction),
1300                                            adr+baseAddress,
1301                                            location->func->size());
1302           assert(retInstance);
1303
1304           //cerr << "created a new return instance (relocated fn)!" << endl;
1305        }
1306     } else {
1307        // It's not a trap-function; it's a "normal" function
1308        // compute the real from address if this instrumentation
1309        // point is from a shared object image
1310        Address baseAddress = 0;
1311        if (proc->getBaseAddress(location->image_ptr,baseAddress)){
1312           adr += baseAddress;           
1313        }
1314
1315        ret = installBaseTramp(location, proc, trampRecursionDesired);
1316        if(!ret) return NULL;
1317        // check to see if this is an entry point and if the delay 
1318        // slot instruction is a call insn, if so, then if the 
1319        // call is to a location within the function, then we need to 
1320        // add an extra instruction after the restore to correctly
1321        // set the o7 register
1322        bool need_to_add = false;
1323        if (location->ipType==functionEntry &&
1324            isInsnType(location->delaySlotInsn,CALLmask,CALLmatch)) {
1325           Address call_offset = location->addr + 8 + 
1326                                 (location->delaySlotInsn.call.disp30<<2);
1327           Address fun_addr = location->func->getAddress(0);
1328           u_int fun_size = location->func->size();
1329           if (call_offset>fun_addr && call_offset<(fun_addr+fun_size)) {
1330              assert(location->isLongJump);
1331              need_to_add = true;
1332           }
1333        }        
1334
1335        if (location->hasNoStackFrame()) {
1336           // if it is the leaf function, we need to generate
1337           // the following instruction sequence:
1338           //     SAVE;      CALL;      NOP.
1339
1340           if (location -> isLongJump == false) {
1341              instruction *insn = new instruction;
1342              generateBranchInsn(insn, (int)(ret->baseAddr-adr));
1343              retInstance = new returnInstance(1, (instructUnion *)insn,
1344                                               sizeof(instruction), adr, 
1345                                               sizeof(instruction));
1346           } else if (need_to_add) {
1347              // generate  original; call; add $o7 imm4 
1348              instruction *insn = new instruction[2];
1349              generateCallInsn(insn, adr+4, (int) ret->baseAddr);
1350              genImmInsn(insn+1,ADDop3,REG_O(7),4,REG_O(7));
1351              retInstance = new returnInstance(2, (instructUnion *)insn,
1352                                  2*sizeof(instruction), adr+4,
1353                                  2*sizeof(instruction));
1354           } else {
1355             bool already_done = false; 
1356             // check to see if the otherInstruction is a call instruction
1357             // to itself, if so then generate the following
1358             // before                   after           basetramp
1359             // ------                   -----           ---------
1360             // mov     originalInsn     mov             sethi
1361             // call    otherInsn        call            save
1362             // sethi   delaySlot        nop             call
1363             //                                          restore
1364             // only generate a call and nop...leave the originalInsn
1365             //
1366             if (isInsnType(location->otherInstruction, CALLmask, CALLmatch)) {
1367               Address offset = location-> func -> getAddress(0)+4 + 
1368                                (location->otherInstruction.call.disp30 << 2);
1369               if ((offset > (location->func->getAddress(0))) && 
1370                   (offset < ((location->func->getAddress(0))+
1371                          location->func->size()))) {
1372                      instruction *insn = new instruction[2];
1373                      generateCallInsn(insn, adr+4, (int) ret->baseAddr);
1374                      generateNOOP(insn+1);
1375                      retInstance = new returnInstance(2, (instructUnion *)insn, 
1376                                              2*sizeof(instruction), adr+4, 
1377                                              2*sizeof(instruction));
1378
1379                      already_done = true;
1380                  }
1381              }
1382
1383              if(!already_done) {
1384                  instruction *insn = new instruction[3];
1385                  genImmInsn(insn, SAVEop3, REG_SPTR, -112, REG_SPTR);
1386                  generateCallInsn(insn+1, adr+4, (int) ret->baseAddr);
1387                  generateNOOP(insn+2);
1388                  retInstance = new returnInstance(3, (instructUnion *)insn, 
1389                                              3*sizeof(instruction), adr, 
1390                                              3*sizeof(instruction));
1391              }  
1392           }
1393                 
1394           assert(retInstance);
1395        } else {
1396           // It's not a leaf.
1397           // Generate branch instruction from the application to the
1398           // base trampoline and no SAVE instruction is needed
1399                 
1400           if (in1BranchInsnRange(adr, ret->baseAddr)) {
1401             // make sure that the isLongJump won't be true
1402             // which only is possible for shlib entry point 
1403             //assert(location->isLongJump == false);
1404             if (location->isLongJump) {
1405               instruction *insn = new instruction[2];   
1406               generateCallInsn(insn, adr, (int) ret->baseAddr);
1407               assert(location->ipType == functionEntry);
1408               generateNOOP(insn+1);
1409               retInstance = new returnInstance(2, (instructUnion *)insn, 
1410                                               2*sizeof(instruction), adr, 
1411                                               2*sizeof(instruction));
1412               assert(retInstance);
1413             } else {
1414               instruction *insn = new instruction;
1415               if (location -> ipType == functionEntry) {
1416                   generateBranchInsn(insn, (int)(ret->baseAddr-adr+sizeof(instruction))); 
1417                   retInstance = new returnInstance(1, (instructUnion *)insn,
1418                                                    sizeof(instruction), 
1419                                                    adr - sizeof(instruction), 
1420                                                    sizeof(instruction));
1421               } else {
1422                   generateBranchInsn(insn,(int)(ret->baseAddr-adr));
1423                   retInstance = new returnInstance(1, (instructUnion *)insn,
1424                                                    sizeof(instruction), 
1425                                                    adr, 
1426                                                    sizeof(instruction));
1427               }
1428             }
1429           } else if(need_to_add) {
1430              // the delay slot instruction is is a call to a location
1431              // within the same function, then need to generate 3 instrs
1432              //    call
1433              //    nop          // delay slot (originally call insn)
1434              //    add o7 imm4  // sets o7 register to correct value
1435              instruction *insn = new instruction[3];    
1436              generateCallInsn(insn, adr, (int) ret->baseAddr);
1437              generateNOOP(insn+1);
1438              genImmInsn(insn+2,ADDop3,REG_O(7),4,REG_O(7));
1439              retInstance = new returnInstance(3, (instructUnion *)insn, 
1440                                               3*sizeof(instruction), adr, 
1441                                               3*sizeof(instruction));
1442           } else {
1443              instruction *insn = new instruction[2];    
1444              generateCallInsn(insn, adr, (int) ret->baseAddr);
1445              if (location -> ipType == functionEntry) {
1446                 if (location -> isLongJump)
1447                    generateNOOP(insn+1);
1448                 else
1449                    genSimpleInsn(insn+1, RESTOREop3, 0, 0, 0);
1450              } else
1451                 generateNOOP(insn+1);
1452
1453              retInstance = new returnInstance(2, (instructUnion *)insn, 
1454                                               2*sizeof(instruction), adr, 
1455                                               2*sizeof(instruction));
1456              assert(retInstance);
1457           }
1458        }
1459     }
1460
1461     proc->baseMap[(const instPoint *)location] = ret;
1462         
1463     return(ret);
1464        // remember, ret was the result of either installBaseTramp() or
1465        // installBaseTrampSpecial()
1466 }
1467
1468 /****************************************************************************/
1469 /****************************************************************************/
1470 /****************************************************************************/
1471
1472 /*
1473  * Install a single tramp.
1474  *
1475  */
1476 void installTramp(instInstance *inst, char *code, int codeSize) 
1477 {
1478     //the default base trampoline template is the regular base trampoline.
1479     //However if the location iptype is  randomPoint then we have to use
1480     //the conservatibve base trampoline which saves the condition codes
1481
1482     trampTemplate* current_template = &baseTemplate;
1483
1484     if(inst->location->ipType == otherPoint)
1485         current_template = &conservativeBaseTemplate;
1486
1487     totalMiniTramps++;
1488     insnGenerated += codeSize/sizeof(int);
1489     
1490     // TODO cast
1491     (inst->proc)->writeDataSpace((caddr_t)inst->trampBase, codeSize, code);
1492
1493     Address atAddr;
1494     if (inst->when == callPreInsn) {
1495         if (inst->baseInstance->prevInstru == false) {
1496             atAddr = inst->baseInstance->baseAddr+current_template->skipPreInsOffset;
1497             inst->baseInstance->cost += inst->baseInstance->prevBaseCost;
1498             inst->baseInstance->prevInstru = true;
1499             generateNoOp(inst->proc, atAddr);
1500         }
1501     } else {
1502         if (inst->baseInstance->postInstru == false) {
1503             atAddr = inst->baseInstance->baseAddr+current_template->skipPostInsOffset; 
1504             inst->baseInstance->cost += inst->baseInstance->postBaseCost;
1505             inst->baseInstance->postInstru = true;
1506             generateNoOp(inst->proc, atAddr);
1507         }
1508     }
1509 }
1510
1511 /****************************************************************************/
1512 /****************************************************************************/
1513 /****************************************************************************/
1514
1515 //This function returns true if the processor on which the daemon is running
1516 //is an ultra SPARC, otherwise returns false.
1517 bool isUltraSparc(){
1518   struct utsname u;
1519   if(uname(&u) < 0){
1520     cerr <<"Trouble in uname(), inst-sparc-solaris.C\n";
1521     return false;
1522   }
1523   if(!strcmp(u.machine, "sun4u")){
1524     return 1;
1525   }
1526   return false;
1527 }
1528
1529 /****************************************************************************/
1530 /****************************************************************************/
1531 /****************************************************************************/
1532
1533 void emitLoadPreviousStackFrameRegister(Address register_num,
1534                                         Register dest,
1535                                         char *insn,
1536                                         Address &base,
1537                                         int size,
1538                                         bool noCost){
1539   if(register_num > 31)
1540     assert(0);
1541   else if(register_num > 15){
1542     /*Need to find it on the stack*/
1543     unsigned frame_offset = (register_num-16) * 4;
1544     /*generate a FLUSHW instruction, in order to make sure that
1545       the registers from the caller are on the caller's stack
1546       frame*/
1547     instruction *in = (instruction *) ((void*)&insn[base]);
1548     if(isUltraSparc())
1549       generateFlushw(in);
1550     else 
1551       generateTrapRegisterSpill(in);
1552     base+=sizeof(instruction);
1553     
1554     if(frame_offset == 0){
1555       emitV(loadIndirOp, 30, 0, dest, insn, base, noCost, size);
1556     }       
1557     else {
1558       emitImm(plusOp,(Register) 30,(RegValue)frame_offset, 
1559               dest, insn, base, noCost);
1560       emitV(loadIndirOp, dest, 0, dest, insn, base, noCost, size);
1561     }
1562   }       
1563   else if(register_num > 7) { 
1564     //out registers become in registers, so we add 16 to the register
1565     //number to find it's value this stack frame. We move it's value
1566     //into the destination register
1567     emitV(orOp, (Register) register_num + 16, 0,  dest, insn, base, false);
1568   }
1569   else /* if(register_num >= 0) */ {
1570     int frame_offset;
1571     if(register_num % 2 == 0) 
1572       frame_offset = (register_num * -4) - 8;
1573     else 
1574       frame_offset = (register_num * -4);
1575     //read globals from the stack, they were saved in tramp-sparc.S
1576     emitImm(plusOp,(Register) 30,(RegValue)frame_offset, 
1577             dest, insn, base, noCost);
1578     emitV(loadIndirOp, dest, 0, dest, insn, base, noCost, size);
1579   }
1580   /* else assert(0); */
1581   
1582 }
1583
1584 /****************************************************************************/
1585 /****************************************************************************/
1586 /****************************************************************************/
1587
1588 Register emitFuncCall(opCode op, 
1589                       registerSpace *rs,
1590                       char *i, Address &base, 
1591                       const vector<AstNode *> &operands, 
1592                       const string &callee, process *proc,
1593                       bool noCost, const function_base *calleefunc)
1594 {
1595         assert(op == callOp);
1596         Address addr;
1597         bool err;
1598         vector <Register> srcs;
1599         void cleanUpAndExit(int status);
1600
1601         if (calleefunc)
1602              addr = calleefunc->getEffectiveAddress(proc);
1603         else {
1604              addr = proc->findInternalAddress(callee, false, err);
1605              if (err) {
1606                   function_base *func = proc->findOneFunction(callee);
1607                   if (!func) {
1608                        ostrstream os(errorLine, 1024, ios::out);
1609                        os << "Internal error: unable to find addr of " << callee << endl;
1610                        showErrorCallback(80, (const char *) errorLine);
1611                        P_abort();
1612                   }
1613                   // TODO: is this correct or should we get relocated address?
1614                   addr = func->getAddress(0);
1615              }
1616         }
1617         for (unsigned u = 0; u < operands.size(); u++)
1618             srcs.push_back(operands[u]->generateCode(proc, rs, i, base, noCost, false));
1619
1620         // TODO cast
1621         instruction *insn = (instruction *) ((void*)&i[base]);
1622
1623         for (unsigned u=0; u<srcs.size(); u++){
1624             if (u >= 5) {
1625                  string msg = "Too many arguments to function call in instrumentation code: only 5 arguments can be passed on the sparc architecture.\n";
1626                  fprintf(stderr, msg.string_of());
1627                  showErrorCallback(94,msg);
1628                  cleanUpAndExit(-1);
1629             }
1630             genSimpleInsn(insn, ORop3, 0, srcs[u], u+8); insn++;
1631             base += sizeof(instruction);
1632             rs->freeRegister(srcs[u]);
1633         }
1634
1635         // As Ling pointed out to me, the following is rather inefficient.  It does:
1636         //   sethi %hi(addr), %o5
1637         //   jmpl %o5 + %lo(addr), %o7   ('call' pseudo-instr)
1638         //   nop
1639         // We can do better:
1640         //   call <addr>    (but note that the call true-instr is pc-relative jump)
1641         //   nop
1642         generateSetHi(insn, addr, 13); insn++;
1643         genImmInsn(insn, JMPLop3, 13, LOW10(addr), 15); insn++;
1644         generateNOOP(insn);
1645
1646         base += 3 * sizeof(instruction);
1647
1648         // return value is the register with the return value from the function.
1649         // This needs to be %o0 since it is back in the caller's scope.
1650         return(REG_O(0));
1651 }
1652  
1653 /****************************************************************************/
1654 /****************************************************************************/
1655 /****************************************************************************/
1656
1657 Address emitA(opCode op, Register src1, Register /*src2*/, Register dest, 
1658               char *i, Address &base, bool /*noCost*/)
1659 {
1660     //fprintf(stderr,"emitA(op=%d,src1=%d,src2=XX,dest=%d)\n",op,src1,dest);
1661
1662     instruction *insn = (instruction *) ((void*)&i[base]);
1663
1664     switch (op) {
1665       case ifOp: {
1666         // cmp src1,0
1667         genImmInsn(insn, SUBop3cc, src1, 0, 0); insn++;
1668         //genSimpleInsn(insn, SUBop3cc, src1, 0, 0); insn++;
1669
1670         insn->branch.op = 0;
1671         insn->branch.cond = BEcond;
1672         insn->branch.op2 = BICCop2;
1673         insn->branch.anneal = false;
1674         insn->branch.disp22 = dest/4;
1675         insn++;
1676
1677         generateNOOP(insn);
1678         base += sizeof(instruction)*3;
1679         return(base - 2*sizeof(instruction));
1680         }
1681       case branchOp: {
1682         // Unconditional branch
1683         generateBranchInsn(insn, dest); insn++;
1684
1685         generateNOOP(insn);
1686         base += sizeof(instruction)*2;
1687         return(base - 2*sizeof(instruction));
1688         }
1689       case trampPreamble: {
1690 #ifdef ndef
1691         // save and restore are done in the base tramp now
1692         genImmInsn(insn, SAVEop3, REG_SPTR, -112, REG_SPTR);
1693         base += sizeof(instruction);
1694         insn++;
1695
1696         // generate code to save global registers
1697         for (unsigned u = 0; u < 4; u++) {
1698           genStoreD(insn, 2*u, REG_FPTR, - (8 + 8*u));
1699           base += sizeof(instruction);
1700           insn++;
1701         }
1702 #endif
1703         return(0);      // let's hope this is expected!
1704         }
1705       case trampTrailer: {
1706 #ifdef ndef
1707         // save and restore are done in the base tramp now
1708         // generate code to restore global registers
1709         for (unsigned u = 0; u < 4; u++) {
1710           genLoadD(insn, REG_FPTR, - (8 + 8*u), 2*u);
1711           base += sizeof(instruction);
1712           insn++;
1713         }
1714
1715         // sequence: restore; nop; b,a back to base tramp; nop
1716         // we can do better.  How about putting the restore in
1717         // the delay slot of the branch instruction, as in:
1718         // b <back to base tramp>; restore
1719         genSimpleInsn(insn, RESTOREop3, 0, 0, 0); 
1720         base += sizeof(instruction);
1721         insn++;
1722
1723         generateNOOP(insn);
1724         base += sizeof(instruction);
1725         insn++;
1726 #endif
1727         // dest is in words of offset and generateBranchInsn is bytes offset
1728         generateBranchInsn(insn, dest << 2);
1729         base += sizeof(instruction);
1730         insn++;
1731
1732         // add no-op, SS-5 sometimes seems to try to decode this insn - jkh 2/14
1733         generateNOOP(insn);
1734         insn++;
1735         base += sizeof(instruction);
1736
1737         return(base -  2 * sizeof(instruction));
1738         }
1739       default:
1740         abort();        // unexpected op for this emit!
1741     }
1742 }
1743
1744 /****************************************************************************/
1745 /****************************************************************************/
1746 /****************************************************************************/
1747
1748 Register emitR(opCode op, Register src1, Register /*src2*/, Register /*dest*/, 
1749               char *i, Address &base, bool /*noCost*/)
1750 {
1751     //fprintf(stderr,"emitR(op=%d,src1=%d,src2=XX,dest=XX)\n",op,src1);
1752
1753     instruction *insn = (instruction *) ((void*)&i[base]);
1754
1755     switch(op) {
1756       case getParamOp: {
1757 #if defined(SHM_SAMPLING) && defined(MT_THREAD)
1758         // saving CT/vector address on the stack
1759         generateStore(insn, REG_MT, REG_FPTR, -40);
1760         insn++;
1761 #endif
1762         // first 8 parameters are in register bank I (24..31)
1763         genSimpleInsn(insn, RESTOREop3, 0, 0, 0);
1764         insn++;
1765
1766         generateStore(insn, REG_I(src1), REG_SPTR, 68+4*src1); 
1767         insn++;
1768               
1769         genImmInsn(insn, SAVEop3, REG_SPTR, -112, REG_SPTR);
1770         insn++;
1771
1772         generateLoad(insn, REG_SPTR, 112+68+4*src1, REG_I(src1)); 
1773         insn++;
1774
1775 #if defined(SHM_SAMPLING) && defined(MT_THREAD)
1776         // restoring CT/vector address back in REG_MT
1777         generateLoad(insn, REG_FPTR, -40, REG_MT);
1778         insn++;
1779         base += 6*sizeof(instruction);
1780 #else
1781         base += 4*sizeof(instruction);
1782 #endif
1783         
1784         if (src1 <= 8) {
1785             return(REG_I(src1));
1786         }
1787         abort();
1788       }
1789     case getSysParamOp: {
1790         if (src1 <= 8) {
1791             return(REG_I(src1));
1792         }       
1793         abort();
1794       }
1795     case getRetValOp: {
1796         // return value is in register REG_I(0)==24
1797         genSimpleInsn(insn, RESTOREop3, 0, 0, 0);
1798         insn++;
1799
1800         generateStore(insn, REG_I(0), REG_SPTR, 68); 
1801         insn++;
1802               
1803         genImmInsn(insn, SAVEop3, REG_SPTR, -112, REG_SPTR);
1804         insn++;
1805
1806         generateLoad(insn, REG_SPTR, 112+68, REG_I(0)); 
1807         insn++;
1808
1809         base += 4*sizeof(instruction);
1810
1811         return(REG_I(0));
1812       }
1813     case getSysRetValOp:
1814         return(REG_I(0));
1815     default:
1816         abort();        // unexpected op for this emit!
1817     }
1818 }
1819
1820 /****************************************************************************/
1821 /****************************************************************************/
1822 /****************************************************************************/
1823
1824 //
1825 // load the original FP (before the dyninst saves) into register dest
1826 //
1827 int getFP(instruction *insn, Register dest)
1828 {
1829     genSimpleInsn(insn, RESTOREop3, 0, 0, 0);
1830     insn++;
1831
1832     generateStore(insn, REG_FPTR, REG_SPTR, 68); 
1833     insn++;
1834           
1835     genImmInsn(insn, SAVEop3, REG_SPTR, -112, REG_SPTR);
1836     insn++;
1837
1838     generateLoad(insn, REG_SPTR, 112+68, dest); 
1839     insn++;
1840
1841     return(4*sizeof(instruction));
1842 }
1843
1844 /****************************************************************************/
1845 /****************************************************************************/
1846 /****************************************************************************/
1847
1848 void emitVload(opCode op, Address src1, Register src2, Register dest, 
1849               char *i, Address &base, bool /*noCost*/, int /* size */)
1850 {
1851     instruction *insn = (instruction *) ((void*)&i[base]);
1852
1853     if (op == loadConstOp) {
1854       // dest = src1:imm    TODO
1855
1856       if ((src1) > ( unsigned )MAX_IMM13 || (src1) < ( unsigned )MIN_IMM13) {
1857             // src1 is out of range of imm13, so we need an extra instruction
1858             generateSetHi(insn, src1, dest);
1859             base += sizeof(instruction);
1860             insn++;
1861
1862             // or regd,imm,regd
1863
1864             // Chance for optimization: we should check for LOW10(src1)==0,
1865             // and if so, don't generate the following bitwise-or instruction,
1866             // since in that case nothing would be done.
1867
1868             genImmInsn(insn, ORop3, dest, LOW10(src1), dest);
1869             base += sizeof(instruction);
1870         } else {
1871             // really or %g0,imm,regd
1872             genImmInsn(insn, ORop3, 0, src1, dest);
1873
1874             base += sizeof(instruction);
1875         }
1876     } else if (op ==  loadOp) {
1877         // dest = [src1]   TODO
1878         generateSetHi(insn, src1, dest);
1879         insn++;
1880
1881         generateLoad(insn, dest, LOW10(src1), dest);
1882
1883         base += sizeof(instruction)*2;
1884     } else if (op ==  loadFrameRelativeOp) {
1885         // return the value that is FP offset from the original fp
1886         //   need to restore old fp and save it on the stack to get at it.
1887
1888         base += getFP(insn, dest);
1889         insn = (instruction *) ((void*)&i[base]);
1890         if (((int) src1 < MIN_IMM13) || ((int) src1 > MAX_IMM13)) {
1891             // offsets are signed!
1892             int offset = (int) src1;
1893
1894             // emit sethi src2, offset
1895             generateSetHi(insn, offset, src2);
1896             base += sizeof(instruction);
1897             insn++;
1898
1899             // or src2, offset, src2
1900             genImmInsn(insn, ORop3, src2, LOW10(offset), src2);
1901             base += sizeof(instruction);
1902             insn++;
1903
1904             // add dest, src2, dest
1905             genSimpleInsn(insn, ADDop3, dest, src2, src2);
1906             base += sizeof(instruction);
1907             insn++;
1908
1909             generateLoad(insn, src2, 0, dest);
1910             insn++;
1911             base += sizeof(instruction);
1912         }  else {
1913             generateLoad(insn, dest, src1, dest);
1914             insn++;
1915             base += sizeof(instruction);
1916         }
1917     } else if (op == loadFrameAddr) {
1918         // offsets are signed!
1919         int offset = (int) src1;
1920
1921         base += getFP(insn, dest);
1922         insn = (instruction *) ((void*)&i[base]);
1923
1924         if (((int) offset < MIN_IMM13) || ((int) offset > MAX_IMM13)) {
1925             // emit sethi src2, offset
1926             generateSetHi(insn, offset, src2);
1927             base += sizeof(instruction);
1928             insn++;
1929
1930             // or src2, offset, src2
1931             genImmInsn(insn, ORop3, src2, LOW10(offset), src2);
1932             base += sizeof(instruction);
1933             insn++;
1934
1935             // add dest, src2, dest
1936             genSimpleInsn(insn, ADDop3, dest, src2, dest);
1937             base += sizeof(instruction);
1938             insn++;
1939         }  else {
1940             // fp is in dest, just add the offset
1941             genImmInsn(insn, ADDop3, dest, offset, dest);
1942             insn++;
1943             base += sizeof(instruction);
1944         }
1945     } else {
1946         abort();       // unexpected op for this emit!
1947     }
1948 }
1949
1950 /****************************************************************************/
1951 /****************************************************************************/
1952 /****************************************************************************/
1953
1954 void emitVstore(opCode op, Register src1, Register src2, Address dest, 
1955               char *i, Address &base, bool /*noCost*/, int /* size */)
1956 {
1957     instruction *insn = (instruction *) ((void*)&i[base]);
1958
1959     if (op == storeOp) {
1960         insn->sethi.op = FMT2op;
1961         insn->sethi.rd = src2;
1962         insn->sethi.op2 = SETHIop2;
1963         insn->sethi.imm22 = HIGH22(dest);
1964         insn++;
1965
1966         generateStore(insn, src1, src2, LOW10(dest));
1967
1968         base += sizeof(instruction)*2;
1969     } else if (op == storeFrameRelativeOp) {
1970         // offsets are signed!
1971         int offset = (int) dest;
1972
1973         base += getFP(insn, src2);
1974         insn = (instruction *) ((void*)&i[base]);
1975
1976         if ((offset < MIN_IMM13) || (offset > MAX_IMM13)) {
1977             // We are really one regsiter short here, so we put the
1978             //   value to store onto the stack for part of the sequence
1979             generateStore(insn, src1, REG_SPTR, 112+68);
1980             base += sizeof(instruction);
1981             insn++;
1982
1983             generateSetHi(insn, offset, src1);
1984             base += sizeof(instruction);
1985             insn++;
1986
1987             genImmInsn(insn, ORop3, src1, LOW10(offset), src1);
1988             base += sizeof(instruction);
1989             insn++;
1990
1991             genSimpleInsn(insn, ADDop3, src1, src2, src2);
1992             base += sizeof(instruction);
1993             insn++;
1994
1995             generateLoad(insn, REG_SPTR, 112+68, src1); 
1996             base += sizeof(instruction);
1997             insn++;
1998
1999             generateStore(insn, src1, src2, 0);
2000             base += sizeof(instruction);
2001             insn++;
2002         } else {
2003             generateStore(insn, src1, src2, offset);
2004             insn++;
2005             base += sizeof(instruction);
2006         }
2007     } else {
2008         abort();       // unexpected op for this emit!
2009     }
2010 }
2011
2012 /****************************************************************************/
2013 /****************************************************************************/
2014 /****************************************************************************/
2015
2016 void emitVupdate(opCode op, RegValue src1, Register /*src2*/, Address dest, 
2017               char *i, Address &base, bool noCost)
2018 {
2019     instruction *insn = (instruction *) ((void*)&i[base]);
2020
2021     if (op == updateCostOp) {
2022         // generate code to update the observed cost.
2023         if (!noCost) {
2024            // sethi %hi(dest), %l0
2025            generateSetHi(insn, dest, REG_L(0));
2026            base += sizeof(instruction);
2027            insn++;
2028   
2029            // ld [%l0+ lo(dest)], %l1
2030            generateLoad(insn, REG_L(0), LOW10(dest), REG_L(1));
2031            base += sizeof(instruction);
2032            insn++;
2033   
2034            // update value (src1 holds the cost, in cycles; e.g. 19)
2035            if (src1 <= MAX_IMM13) {
2036               genImmInsn(insn, ADDop3, REG_L(1), src1, REG_L(1));
2037               base += sizeof(instruction);
2038               insn++;
2039
2040               generateNOOP(insn);
2041               base += sizeof(instruction);
2042               insn++;
2043
2044               generateNOOP(insn);
2045               base += sizeof(instruction);
2046               insn++;
2047            } else {
2048               // load in two parts
2049               generateSetHi(insn, src1, REG_L(2));
2050               base += sizeof(instruction);
2051               insn++;
2052
2053               // or regd,imm,regd
2054               genImmInsn(insn, ORop3, REG_L(2), LOW10(src1), REG_L(2));
2055               base += sizeof(instruction);
2056               insn++;
2057
2058               // now add it
2059               genSimpleInsn(insn, ADDop3, REG_L(1), REG_L(2), REG_L(1));
2060               base += sizeof(instruction);
2061               insn++;
2062            }
2063   
2064            // store result st %l1, [%l0+ lo(dest)];
2065            generateStore(insn, REG_L(1), REG_L(0), LOW10(dest));
2066            base += sizeof(instruction);
2067            insn++;
2068         }
2069     } else {
2070         abort();       // unexpected op for this emit!
2071     }
2072 }
2073
2074 /****************************************************************************/
2075 /****************************************************************************/
2076 /****************************************************************************/
2077
2078 void emitV(opCode op, Register src1, Register src2, Register dest, 
2079               char *i, Address &base, bool /*noCost*/, int /* size */)
2080 {
2081     //fprintf(stderr,"emitV(op=%d,src1=%d,src2=%d,dest=%d)\n",op,src1,src2,dest);
2082
2083     assert ((op!=branchOp) && (op!=ifOp) && 
2084             (op!=trampTrailer) && (op!=trampPreamble));         // !emitA
2085     assert ((op!=getRetValOp) && (op!=getSysRetValOp) &&
2086             (op!=getParamOp) && (op!=getSysParamOp));           // !emitR
2087     assert ((op!=loadOp) && (op!=loadConstOp));                 // !emitVload
2088     assert ((op!=storeOp));                                     // !emitVstore
2089     assert ((op!=updateCostOp));                                // !emitVupdate
2090
2091     instruction *insn = (instruction *) ((void*)&i[base]);
2092
2093     if (op == loadIndirOp) {
2094         generateLoad(insn, src1, 0, dest);
2095         base += sizeof(instruction);
2096     } else if (op == storeIndirOp) {
2097         generateStore(insn, src1, dest, 0);
2098         base += sizeof(instruction);
2099     } else if (op == noOp) {
2100         generateNOOP(insn);
2101         base += sizeof(instruction);
2102     } else if (op == saveRegOp) {
2103         // should never be called for this platform.
2104         abort();
2105     } else {
2106       int op3=-1;
2107         switch (op) {
2108             // integer ops
2109             case plusOp:
2110                 op3 = ADDop3;
2111                 break;
2112
2113             case minusOp:
2114                 op3 = SUBop3;
2115                 break;
2116
2117             case timesOp:
2118                 op3 = SMULop3;
2119                 break;
2120
2121             case divOp:
2122                 op3 = SDIVop3;
2123                 //need to set the Y register to Zero, Zhichen
2124                 genImmInsn(insn, WRYop3, REG_G(0), 0, 0);
2125                 base += sizeof(instruction);
2126                 insn = (instruction *) ((void*)&i[base]);
2127                 break;
2128
2129             // Bool ops
2130             case orOp:
2131                 op3 = ORop3;
2132                 break;
2133
2134             case andOp:
2135                 op3 = ANDop3;
2136                 break;
2137
2138             // rel ops
2139             // For a particular condition (e.g. <=) we need to use the
2140             // the opposite in order to get the right value (e.g. for >=
2141             // we need BLTcond) - naim
2142             case eqOp:
2143                 genRelOp(insn, BNEcond, src1, src2, dest, base);
2144                 return;
2145                 break;
2146
2147             case neOp:
2148                 genRelOp(insn, BEcond, src1, src2, dest, base);
2149                 return;
2150                 break;
2151
2152             case lessOp:
2153                 genRelOp(insn, BGEcond, src1, src2, dest, base);
2154                 return;
2155                 break;
2156
2157             case leOp:
2158                 genRelOp(insn, BGTcond, src1, src2, dest, base);
2159                 return;
2160                 break;
2161
2162             case greaterOp:
2163                 genRelOp(insn, BLEcond, src1, src2, dest, base);
2164                 return;
2165                 break;
2166
2167             case geOp:
2168                 genRelOp(insn, BLTcond, src1, src2, dest, base);
2169                 return;
2170                 break;
2171
2172             default:
2173                 abort();
2174                 break;
2175         }
2176         genSimpleInsn(insn, op3, src1, src2, dest);
2177
2178         base += sizeof(instruction);
2179       }
2180    return;
2181 }
2182
2183 /****************************************************************************/
2184 /****************************************************************************/
2185 /****************************************************************************/
2186
2187 static inline bool isRestoreInsn(instruction i) {
2188     return (i.rest.op == 2 \
2189                && ((i.rest.op3 == ORop3 && i.rest.rd == 15)
2190                        || i.rest.op3 == RESTOREop3));
2191 }
2192
2193 /****************************************************************************/
2194 /****************************************************************************/
2195 /****************************************************************************/
2196
2197 static inline bool CallRestoreTC(instruction instr, instruction nexti) {
2198     return (isCallInsn(instr) && isRestoreInsn(nexti));
2199 }
2200
2201 /*
2202     Return integer value indicating whether instruction sequence
2203      found signals tail call 
2204      jmp 
2205      nop 
2206     sequence.  Note that this should NOT include jmpl nop, ret nop, retl
2207      nop....
2208     Current heuristic to detect such sequences :
2209      look for jmp %reg, nop in function w/ no stack frame, if jmp, nop
2210      are last 2 instructions, return 1 (definate TC), at any other point,
2211      return 0 (not TC).  Otherwise, return 0 (no TC).
2212      w/ no stack frame....
2213     instr is instruction being examioned.
2214     nexti is instruction after
2215     addr is address of <instr>
2216     func is pointer to function class object describing function
2217      instructions come from....
2218  */
2219 static inline bool JmpNopTC(instruction instr, instruction nexti,
2220                             Address addr, pd_Function *func) {
2221
2222     if (!isInsnType(instr, JMPLmask, JMPLmatch)) {
2223         return 0;
2224     }
2225
2226     assert(instr.resti.op3 == 0x38);
2227
2228     // only looking for jump instructions which don't overwrite a register
2229     //  with the PC which the jump comes from (g0 is hardwired to 0, so a write
2230     //  there has no effect?)....  
2231     //  instr should have gdb disass syntax : 
2232     //      jmp  %reg, 
2233     //  NOT jmpl %reg1, %reg2
2234     if (instr.resti.rd != REG_G(0)) {
2235         return 0;
2236     }
2237
2238     // only looking for jump instructions in which the destination is
2239     //  NOT %i7 + 8/12/16 or %o7 + 8/12/16 (ret and retl synthetic 
2240     //  instructions, respectively)
2241     if (instr.resti.i == 1) {
2242         if (instr.resti.rs1 == REG_I(7) || instr.resti.rs1 == REG_O(7)) {
2243             // NOTE : some return and retl instructions jump to {io}7 + 12,
2244             //  or (io)7 + 16, not + 8, to have some extra space to store the size of a 
2245             //  return structure....
2246             if (instr.resti.simm13 == 0x8 || instr.resti.simm13 == 12 ||
2247                     instr.resti.simm13 == 16) {
2248                 return 0;
2249             }
2250         }
2251     }  
2252
2253     // jmp, foloowed by NOP....
2254     if (!isNopInsn(nexti)) {
2255         return 0;
2256     }
2257
2258     // in function w/o stack frame....
2259     if (!func->hasNoStackFrame()) {
2260         return 0;
2261     }
2262
2263     // if sequence is detected, but not at end of fn 
2264     //  (last 2 instructions....), return value indicating possible TC.
2265     //  This should (eventually) mark the fn as uninstrumenatble....
2266     if (addr != (func->getAddress(0) + func->size() - 8)) {
2267         return 0;
2268     }
2269
2270     return 1;
2271 }
2272
2273 /****************************************************************************/
2274 /****************************************************************************/
2275 /****************************************************************************/
2276
2277 /*
2278   Is the specified call instruction one whose goal is to set the 07 register
2279   (the sequence of execution is as if the call instruction did not change the
2280   control flow, and the O7 register is set)?
2281
2282   here, we define a call whose goal is to set the 07 regsiter
2283     as one where the target is the call address + 8, AND where that
2284     target is INSIDE the same function (need to make sure to check for that
2285     last case also, c.f. function DOW, which ends with):
2286      0xef601374 <DOW+56>:    call  0xef60137c <adddays>
2287      0xef601378 <DOW+60>:    restore 
2288
2289   instr - raw instruction....
2290   functionSize - size of function (in bytes, NOT # instructions)....
2291   instructionOffset - BYTE offset in function at which instr occurs....
2292  */        
2293 static inline bool is_set_O7_call(instruction instr, unsigned functionSize, 
2294                               unsigned instructionOffset) {
2295     // if the instruction is call %register, assume that it is NOT a 
2296     //  call designed purely to set %O7....
2297     if(instr.call.op != CALLop) {
2298         return false;
2299     }
2300     if (((instr.call.disp30 << 2) == 8) && 
2301              (instructionOffset < (functionSize - 2 * sizeof(instruction)))) {
2302         return true; 
2303     }
2304     return false; 
2305 }  
2306
2307 /****************************************************************************/
2308 /****************************************************************************/
2309 /****************************************************************************/
2310
2311 /*
2312     Does the specified call instruction call to target inside function
2313     or outside - may be indeterminate if insn is call %reg instead of 
2314     call <address> (really call PC + offset)
2315     Note: (recursive) calls back to the beginning of the function are OK
2316     since we really want to consider these as instrumentable call sites!
2317  */
2318 enum fuzzyBoolean {eFalse = 0, eTrue = 1, eDontKnow = 2}; 
2319
2320 static enum fuzzyBoolean is_call_outside_function(const instruction instr,
2321                 const Address functionStarts, const Address instructionAddress, 
2322                 const unsigned int functionSize) 
2323 {
2324     // call %register - don't know if target inside function....
2325     if(instr.call.op != CALLop) {
2326         return eDontKnow;
2327     }
2328     const Address call_target = instructionAddress + (instr.call.disp30 << 2);
2329     if ((call_target > functionStarts) && 
2330         (call_target < (functionStarts + functionSize))) {
2331         return eFalse;
2332     }
2333     return eTrue;
2334 }
2335
2336
2337 /****************************************************************************/
2338 /****************************************************************************/
2339 /****************************************************************************/
2340
2341 /*
2342  * Find the instPoints of this function.
2343  */
2344 bool pd_Function::findInstPoints(const image *owner) {
2345
2346   Address firstAddress = getAddress(0);
2347   Address lastAddress = getAddress(0) + size();
2348   Address adr;
2349   Address target;
2350   Address entry;
2351   Address disp;
2352
2353   instruction instr; 
2354   instruction nexti;
2355
2356   // For determining if function needs relocation to be instrumented
2357   isTrap = false;
2358   relocatable_ = false;
2359   bool canBeRelocated = true;
2360
2361   // Initially assume function has no stack frame 
2362   noStackFrame = true;
2363
2364   // variables for function parameters
2365   const instPoint *blah = 0;
2366   bool err;
2367   bool dummyParam;
2368
2369   // Ids for instPoints
2370   unsigned retId = 0;
2371   unsigned callsId = 0; 
2372
2373   if (size() == 0) {
2374     return false;
2375   } 
2376
2377   instr.raw = owner->get_instruction(firstAddress);
2378   if (!IS_VALID_INSN(instr)) {
2379     return false;
2380   }
2381
2382   // Determine if function needs to be relocated when instrumented
2383   for ( adr = firstAddress; adr < lastAddress; adr += 4) { 
2384     instr.raw = owner->get_instruction(adr);
2385     nexti.raw = owner->get_instruction(adr+4);
2386
2387     // If there's an TRAP instruction in the function, we assume
2388     // that it is an system call and will relocate it to the heap
2389     if (isInsnType(instr, TRAPmask, TRAPmatch)) {
2390       isTrap = true;
2391       relocatable_ = true;
2392     } 
2393
2394     // TODO: This is a hacking for the solaris(solaris2.5 actually)
2395     // We will relocate that function if the function has been 
2396     // tail-call optimazed.
2397     // (Actully, the reason of this is that the system calls like 
2398     //  read, write, etc have the tail-call optimazation to call
2399     //  the _read, _write etc. which contain the TRAP instruction 
2400     //  This is only done if libc is statically linked...if the
2401     //  libTag is set, otherwise we instrument read and _read
2402     //  both for the dynamically linked case
2403     // New for Solaris 2.6 support - new form of tail-call opt-
2404     //  imization found:
2405     //   jmp %register
2406     //   nop
2407     //  as last 2 instructions in function which does not have
2408     //  own register frame.
2409     if (CallRestoreTC(instr, nexti) || JmpNopTC(instr, nexti, adr, this)) {
2410       isTrap = true;
2411       relocatable_ = true;
2412     }
2413
2414     // if call is directly to a retl, this is not a real call, but
2415     // is instead used to set the o7 register. Set the function to be
2416     // relocated when instrumented.
2417     if (isCallInsn(instr)) {
2418
2419       // find target address of call
2420       disp = instr.call.disp30 << 2;
2421       target = adr + disp;
2422
2423       // get target instruction of the call   
2424       instruction tmpInsn;
2425       tmpInsn.raw = owner->get_instruction( target );
2426
2427       if((tmpInsn.raw & 0xfffff000) == 0x81c3e000) {
2428         isTrap = true;
2429         relocatable_ = true;
2430       }
2431     }
2432   }
2433
2434
2435   /* FIND FUNCTION ENTRY */
2436
2437   entry = firstAddress;
2438   for ( adr = firstAddress; adr < lastAddress; adr += 4) { 
2439
2440     // The function Entry is defined as the first SAVE instruction plus
2441     // the instructions after this.
2442     // ( The first instruction for the nonleaf function is not 
2443     //   necessarily a SAVE instruction. ) 
2444     instr.raw = owner->get_instruction(adr);
2445
2446     if (isInsnType(instr, SAVEmask, SAVEmatch)) {
2447       entry = adr;
2448       noStackFrame = false;
2449       continue;
2450     }
2451   }
2452
2453   // If there's no SAVE instruction found, this is a leaf function
2454   // and function Entry will be defined from the first instruction
2455   if (noStackFrame) {
2456
2457     // noStackFrame, apparently leaf function
2458     adr = firstAddress;
2459     entry = adr;
2460   }
2461
2462
2463
2464   /* CHECK IF FUNCTION SHOULD NOT BE RELOCATED WHEN INSTRUMENTED */
2465
2466   // FUNCTION TOO SMALL
2467   if (size() <= 3*sizeof(instruction)) {
2468     canBeRelocated = false;
2469   }
2470
2471
2472   // if the second instruction in a function that needs relocation is a call
2473   // instruction or a branch instruction, then we can't deal with this.
2474   // New: only a problem if the call is to a location outside the function, 
2475   // or is a jump to itself....
2476
2477   // Grab second instruction
2478   Address addrSecondInstr = firstAddress + sizeof(instruction);
2479   instr.raw = owner->get_instruction(addrSecondInstr); 
2480
2481   if ( isCallInsn(instr) ) {
2482
2483     // target of call
2484     target = addrSecondInstr + (instr.call.disp30 << 2);
2485
2486     // if call dest. is outside of function, assume real
2487     // call site.  Assuming cant deal with this case!!!!
2488     if ( !(target >= firstAddress && target <= lastAddress) ||
2489                                     (target == addrSecondInstr) ) {
2490       canBeRelocated = false;
2491     }
2492
2493     // Branch instruction  
2494     if ( instr.branch.op == 0 && 
2495         (instr.branch.op2 == 2 || instr.branch.op2 == 6) ) {
2496       canBeRelocated = false;
2497     }
2498   }
2499
2500
2501   // Can't handle function
2502   if (canBeRelocated == false && isTrap == true) {
2503     return false;
2504   }
2505
2506
2507 #ifdef BPATCH_LIBRARY
2508   if (BPatch::bpatch->hasForcedRelocation_NP()) {
2509     if (canBeRelocated == true) {
2510       isTrap = true;
2511       relocatable_ = true;
2512     }
2513   }
2514 #endif
2515
2516
2517   /* CREATE ENTRY INSTPOINT */
2518   instr.raw = owner->get_instruction(entry);
2519
2520   if (relocatable_ == true) {
2521     funcEntry_ = new instPoint(this, instr, owner, entry, true, 
2522                                           functionEntry, entry);
2523   } else {
2524       funcEntry_ = new instPoint(this, instr, owner, entry, true, 
2525                                                  functionEntry);
2526   }
2527
2528   assert(funcEntry_);
2529
2530
2531   // ITERATE OVER INSTRUCTIONS, locating instPoints
2532   adr = firstAddress;
2533
2534   for (int i=0; adr < lastAddress; adr += sizeof(instruction), i++) {
2535
2536     instr.raw = owner->get_instruction(adr);
2537     newInstr[i] = instr;
2538     nexti.raw = owner->get_instruction(adr+4);
2539
2540     // check for return insn and as a side affect decide if we are at the
2541     //   end of the function.
2542     if (isReturnInsn(owner, adr, dummyParam, prettyName())) {
2543       // define the return point
2544
2545       instPoint *point;
2546       if (relocatable_ == true) {
2547         point = new instPoint(this, instr, owner, adr, false, 
2548                                            functionExit, adr);
2549       } else {
2550           point = new instPoint(this, instr, owner, adr, false, 
2551                                                   functionExit);
2552       }
2553
2554       funcReturns.push_back(point);
2555       funcReturns[retId] -> instId = retId; retId++;
2556     } 
2557     
2558     else if (instr.branch.op == 0      
2559               &&  (instr.branch.op2 == 2 || instr.branch.op2 == 6) 
2560               && (instr.branch.cond == 0 || instr.branch.cond == 8)) {
2561
2562       // find if this branch is going out of the function
2563       disp = instr.branch.disp22;
2564       Address target = adr +  (disp << 2);
2565          
2566       if (target < firstAddress || target >= lastAddress) {
2567
2568         instPoint *point;
2569         if (relocatable_ == true) {
2570           point = new instPoint(this, newInstr[i], owner, adr, 
2571                                      false, functionExit, adr);
2572         } else {
2573             point = new instPoint(this, newInstr[i], owner, adr, 
2574                                             false, functionExit);
2575         }
2576
2577         if ((instr.branch.cond != 0) && (instr.branch.cond != 8)) {  
2578
2579           point->isBranchOut = true;
2580           point->branchTarget = target;
2581         }
2582
2583         funcReturns.push_back(point);
2584         funcReturns[retId] -> instId = retId; retId++;
2585
2586       }
2587     } 
2588     
2589     else if (isCallInsn(instr)) {
2590
2591       // if the call target is the address of the call instruction
2592       // then this is not something that we can instrument...
2593       // this occurs in functions with code that is modifined when 
2594       // they are loaded by the run-time linker, or when the .init
2595       // section is executed.  In this case the instructions in the
2596       // parsed image file are different from the ones in the executable
2597       // process.
2598       Address call_target = adr + (instr.call.disp30 << 2);
2599       if(instr.call.op == CALLop) { 
2600         if(call_target == adr){ 
2601           cerr << "WARN : function " << prettyName().string_of()
2602                << " has call to same location as call, NOT instrumenting"
2603                << endl;
2604           return false;
2605         }
2606       }
2607
2608       // first, check for tail-call optimization: a call where the 
2609       // instruction in the delay slot write to register %o7(15), usually 
2610       // just moving the caller's return address, or doing a restore
2611       // Tail calls are instrumented as return points, not call points.
2612
2613       if (CallRestoreTC(instr, nexti)) {
2614
2615         adr = newCallPoint(adr, instr, owner, err, callsId, adr, 0, blah);
2616         if (err) {
2617           return false;
2618         }
2619
2620         disp = adr + sizeof(instruction);
2621         instPoint *point = new instPoint(this, instr, owner, disp, 
2622                                          false, functionExit, adr);
2623         funcReturns.push_back(point);
2624         funcReturns[retId] -> instId = retId; retId++;
2625
2626       } else {
2627
2628           // check if the call is to inside the function - if definately
2629           // inside function (meaning that thew destination can be determined
2630           // statically because its a call to an address, not to a register 
2631           // or register + offset) then don't instrument as call site, 
2632           // otherwise (meaning that the call destination is known statically 
2633           // to be outside the function, or is not known statically), then 
2634           // instrument as a call site....
2635           enum fuzzyBoolean is_inst_point;
2636           is_inst_point = is_call_outside_function(instr, firstAddress, 
2637                                                            adr, size());
2638           if (is_inst_point == eFalse) {
2639
2640             // if this is a call instr to a location within the function, 
2641             // and if the offest is not 8 then do not define this function 
2642             if (!is_set_O7_call(instr, size(), adr - firstAddress)) {
2643               return false;
2644             }
2645             adr = newCallPoint(adr, instr, owner, err, callsId, adr, 0, blah);
2646
2647           } else {
2648  
2649               // get call target instruction   
2650               Address call_target = adr + (instr.call.disp30 << 2);
2651               instruction tmpInsn;
2652               tmpInsn.raw = owner->get_instruction( call_target );
2653
2654               // check that call is not directly to a retl instruction,
2655               // and thus a real call
2656               if((tmpInsn.raw & 0xfffff000) != 0x81c3e000) {
2657                   adr = newCallPoint(adr, instr, owner, err, callsId, 
2658                                                         adr, 0, blah);
2659                 if (err) {
2660                   return false;
2661                 }
2662               } 
2663           }         
2664       }
2665     }
2666
2667     else if (JmpNopTC(instr, nexti, adr, this)) {
2668
2669       adr = newCallPoint(adr, instr, owner, err, callsId, adr, 0, blah);
2670       if (err) {
2671         return false;
2672       }
2673
2674       disp = adr + sizeof(instruction);
2675       instPoint *point = new instPoint(this, instr, owner, disp, false, 
2676                                                      functionExit, adr);
2677       funcReturns.push_back(point);
2678       funcReturns[retId] -> instId = retId; retId++;
2679     }
2680
2681     else if (isInsnType(instr, JMPLmask, JMPLmatch)) {
2682        /* A register indirect jump. Some jumps may exit the function 
2683           (e.g. read/write on SunOS). In general, the only way to 
2684           know if a jump is exiting the function is to instrument
2685           the jump to test if the target is outside the current 
2686           function. Instead of doing this, we just check the 
2687           previous two instructions, to see if they are loading
2688           an address that is out of the current function.
2689           This should catch the most common cases (e.g. read/write).
2690           For other cases, we would miss a return point.
2691
2692           This is the case considered:
2693
2694              sethi addr_hi, r
2695              or addr_lo, r, r
2696              jump r
2697         */
2698
2699       Register jumpreg = instr.rest.rs1;
2700       instruction prev1;
2701       instruction prev2;
2702
2703       prev1.raw = owner->get_instruction(adr-4);
2704       prev2.raw = owner->get_instruction(adr-8);
2705
2706       Address targetAddr;
2707
2708       if (instr.rest.rd == 0 && (instr.rest.i == 1 || instr.rest.rs2 == 0)
2709           && prev2.sethi.op == FMT2op && prev2.sethi.op2 == SETHIop2 
2710           && prev2.sethi.rd == (unsigned)jumpreg
2711           && prev1.rest.op == RESTop 
2712           && prev1.rest.rd == (unsigned)jumpreg && prev1.rest.i == 1
2713           && prev1.rest.op3 == ORop3 && prev1.rest.rs1 == (unsigned)jumpreg) {
2714
2715         targetAddr = (prev2.sethi.imm22 << 10) & 0xfffffc00;
2716         targetAddr |= prev1.resti.simm13;
2717
2718         if ( (targetAddr < firstAddress) || (targetAddr >= lastAddress) ){
2719
2720           instPoint *point;
2721           if (relocatable_ == true) {
2722             point = new instPoint(this, instr, owner, adr, false, 
2723                                                functionExit, adr);
2724           } else {
2725               point = new instPoint(this, instr, owner, adr, false, 
2726                                                       functionExit);
2727           }
2728
2729           funcReturns.push_back(point);
2730           funcReturns[retId] -> instId = retId; retId++;
2731         }
2732       }
2733     }
2734   }
2735      
2736   bool checkPoints = checkInstPoints(owner);
2737
2738   if ( (checkPoints == false) || (!canBeRelocated && isTrap) ){
2739     return false;
2740   }
2741
2742   return true;
2743 }
2744
2745 /****************************************************************************/
2746 /****************************************************************************/
2747 /****************************************************************************/
2748
2749 /*
2750  * Check all the instPoints within this function to see if there's 
2751  * any conficts happen.
2752  */
2753 bool pd_Function::checkInstPoints(const image *owner) {
2754
2755     // Our own library function, skip the test.
2756     if (prettyName().prefixed_by("DYNINST")) 
2757         return true;
2758
2759 #ifndef BPATCH_LIBRARY /* XXX Users of libdyninstAPI might not agree. */
2760     // The function is too small to be worthing instrumenting.
2761     if (size() <= 12){
2762         //cerr << "WARN : function " << prettyName().string_of()
2763         //           << " too small (size <= 12), can't instrument" << endl;
2764         return false;
2765     }
2766 #endif
2767
2768     // No function return! return false;
2769     if (sizeof(funcReturns) == 0) {
2770         //cerr << "WARN : function " << prettyName().string_of()
2771         //           << " no return point found, can't instrument" << endl;
2772         return false;
2773     }
2774
2775     instruction instr;
2776     Address adr = getAddress(0);
2777
2778     bool retl_inst = false;
2779     bool restore_inst = false;
2780     // Check if there's any branch instruction jump to the middle
2781     // of the instruction sequence in the function entry point
2782     // and function exit point.
2783     for ( ; adr < getAddress(0) + size(); adr += sizeof(instruction)) {
2784
2785         instr.raw = owner->get_instruction(adr);
2786         if(isInsnType(instr, RETLmask, RETLmatch)) retl_inst = true;
2787         if(isInsnType(instr, RESTOREmask, RESTOREmatch)) restore_inst = true;
2788         if (isInsnType(instr, BRNCHmask, BRNCHmatch)||
2789             isInsnType(instr, FBRNCHmask, FBRNCHmatch)) {
2790
2791             int disp = instr.branch.disp22;
2792             Address target = adr + (disp << 2);
2793
2794             if ((target > funcEntry_->addr)&&
2795                 (target < (funcEntry_->addr + funcEntry_->size))) {
2796                 if (adr > (funcEntry_->addr+funcEntry_->size)){
2797                     //cerr << "WARN : function " << prettyName().string_of()
2798                     //   << " has branch target inside fn entry point, can't instrument" << endl;
2799                   //return false;
2800
2801                   // function can be instrumented if we relocate it
2802                   isTrap = true; 
2803                   relocatable_ = true;
2804             } }
2805
2806             for (u_int i = 0; i < funcReturns.size(); i++) {
2807                 if ((target > funcReturns[i]->addr)&&
2808                     (target < (funcReturns[i]->addr + funcReturns[i]->size))) {
2809                     if ((adr < funcReturns[i]->addr)||
2810                         (adr > (funcReturns[i]->addr + funcReturns[i]->size))){
2811                         //cerr << "WARN : function " << prettyName().string_of()
2812                         //  << " has branch target inside fn return point, "
2813                         //  << "can't instrument" << endl;
2814                       //return false;
2815
2816                       // function can be instrumented if we relocate it
2817                       isTrap = true;
2818                       relocatable_ = true; 
2819                 } }
2820             }
2821         }
2822     }
2823
2824     // if there is a retl instruction and we don't think this is a leaf
2825     // function then this is a way messed up function...well, at least we
2826     // we can't deal with this...the only example I can find is _cerror
2827     // and _cerror64 in libc.so.1
2828     if(retl_inst && !noStackFrame && !restore_inst){ 
2829         //cerr << "WARN : function " << prettyName().string_of()
2830         //     << " retl instruction in non-leaf function, can't instrument"
2831         //      << endl;
2832         return false;
2833     }
2834
2835     // check that no instrumentation points could overlap
2836     Address func_entry = funcEntry_->addr + funcEntry_->size; 
2837     for (u_int i = 0; i < funcReturns.size(); i++) {
2838         if(func_entry >= funcReturns[i]->addr){
2839           //return false;
2840
2841           // function can be instrumented if we relocate it 
2842           isTrap = true;
2843           relocatable_ = true; 
2844         }
2845         if(i >= 1){ // check if return points overlap
2846             Address prev_exit = funcReturns[i-1]->addr+funcReturns[i-1]->size;  
2847             if(funcReturns[i]->addr < prev_exit) {
2848                 //cerr << "WARN : function " << prettyName().string_of()
2849                 //     << " overlapping instrumentation points, can't instrument"
2850                 //     << endl;
2851               //return false;
2852               // function can be instrumented if we relocate it 
2853               isTrap = true; 
2854               relocatable_ = true;
2855             } 
2856         }
2857     }
2858
2859     return true;        
2860 }
2861
2862 /****************************************************************************/
2863 /****************************************************************************/
2864 /****************************************************************************/
2865
2866 // used for sorting inst points - typecast void *s to instPoint **s, then
2867 //  do {-1, 0, 1} comparison by address....
2868 int sort_inst_points_by_address(const void *arg1, const void *arg2) {
2869     instPoint * const *a = static_cast<instPoint* const *>(arg1);
2870     instPoint * const *b = static_cast<instPoint* const *>(arg2);
2871     if ((*a)->iPgetAddress() > (*b)->iPgetAddress()) {
2872         return 1;
2873     } else if ((*a)->iPgetAddress() < (*b)->iPgetAddress()) {
2874         return -1;
2875     }
2876     return 0;
2877 }
2878
2879 /****************************************************************************/
2880 /****************************************************************************/
2881 /****************************************************************************/
2882
2883 /*
2884   First pass, handle cases where general-purpose re-writing needs to be
2885   done to preserve paradynd/dyninstAPI's assumptions about function
2886   structure.  
2887     In current sparc-solaris version, this is ONLY the following cases:
2888       If a call site and return point overlap and are located directly
2889        next to eachother, and the return point is located on a 
2890        restore operation, then a TailCallPA is applied whose footprint
2891        covers the call and the restore.
2892        The TailCallPA should rewrite the call; restore, and update the 
2893        locations of both inst points as necessary.
2894       If the 2nd instruction in a function is a CALL, then a single nop
2895        is inserted before the call - to clear out the delay slot of the
2896        branch which is inserted at the first instruction (for entry point
2897        instrumentation).
2898        If the dyninstAPI is seperated from paradyn, or when converting this 
2899        code to support instrumentation at arbitrary points (instead of assuming
2900        entry, exit, and call site instrumentation), then the check should be 
2901        changed from:
2902          look at 2nd insn, see if its a call
2903         TO
2904          look at all inst points, see if any of them have a call in what
2905          corresponds to the delay slot of the instruction which is going to
2906          get stomped by a branch/call to tramp....
2907       If the code has any calls to address (of call) + 8, replace the call with
2908         a sequence which sets the 07 register to the (original) address....
2909   Function:
2910     Attaches LocalAlterations related to general rewrites of function
2911      (by adding them to LocalAlterationSet p).
2912     returns boolean value indicating whether it was able to figure out
2913     sequence of LocalAlterations to apply to perform specified rewrites....
2914  */
2915 bool pd_Function::PA_attachGeneralRewrites( const image *owner,
2916                                             LocalAlterationSet *p, 
2917                                             Address baseAddress, 
2918                                             Address firstAddress, 
2919                                             instruction loadedCode[], 
2920                                             unsigned /* numInstructions */,
2921                                             int codeSize ) {
2922     instruction instr, nexti;
2923     TailCallOptimization *tail_call;
2924     // previously referred to calls[i] directly, but gdb seems to be having
2925     //  trouble with templated types with the new compiler - making debugging
2926     //  difficult - so, directly assign calls[i] to the_call so can use gdb
2927     //  to get at info about it....
2928     instPoint *the_call;
2929
2930 #ifdef DEBUG_PA_INST
2931     cerr << "pd_Function::PA_attachGeneralRewrites called" <<endl;
2932     cerr << " prettyName = " << prettyName() << endl;
2933 #endif
2934
2935     // Look at the 2nd instruction in function.  If its a call, then
2936     //  stick a single nop before it....
2937     // The comment in the old inst-sparc-solaris.C version describing the rationale
2938     // for thw change is :
2939     //   if the second instruction in the function is a call instruction
2940     //   then this cannot go in the delay slot of the branch to the
2941     //   base tramp, so add a noop between first and second instructions
2942     //   in the relocated function (check out write in libc.so.1 for
2943     //   and example of this):
2944     //
2945     //     save  %sp, -96, %sp             brach to base tramp
2946     //     call  0x73b70                   nop
2947     //                                     call 0x73b70
2948     //    Note that if this call insn is a call to address + 8, it will actually
2949     //     be replaced by a sequence which does NOT include a call, so don't need to
2950     //     worry about inserting the extra nop....
2951     if (isCallInsn(loadedCode[1]) && 
2952                 !is_set_O7_call(loadedCode[1], codeSize, sizeof(instruction))) {
2953         // Insert one no-op after the first instruction
2954         // (RewriteFootprint will copy the instruction at offset 0, and then
2955         // place the no-op after that instruction)   
2956         InsertNops *nop = new InsertNops(this, 0, sizeof(instruction));
2957         p->AddAlteration(nop);
2958 #ifdef DEBUG_PA_INST
2959         cerr << " added single NOP in 2nd instruction" << endl;
2960 #endif
2961     }
2962
2963     // Iterate over function instruction by instruction, looking for calls to
2964     //  address + 8....
2965     assert((codeSize % sizeof(instruction)) == 0);
2966     for(unsigned i=0;i<(codeSize/sizeof(instruction));i++) {
2967         //  want CALL %address, NOT CALL %register
2968         if (isTrueCallInsn(loadedCode[i])) {
2969             // figure out destination of call....
2970             if (is_set_O7_call(loadedCode[i], codeSize, i * sizeof(instruction))) {
2971                 SetO7 *seto7 = new SetO7(this, i * sizeof(instruction));
2972                 p->AddAlteration(seto7);
2973 #ifdef DEBUG_PA_INST
2974                 cerr << " detected call pattern designed to set 07 register at offset " 
2975                      <<  i * sizeof(instruction) << endl;
2976 #endif
2977             } else {
2978
2979                 // Check for a call to a location outside of the function, 
2980                 // where the target of the call is a retl instruction. This 
2981                 // sequence is used to set the o7 register with the PC.
2982
2983                 // Get target of call instruction
2984                 Address callAddress = firstAddress + i*sizeof(instruction);
2985                 Address callTarget  = callAddress + 
2986                                       (loadedCode[i].call.disp30 << 2);
2987
2988                 // If call is to location outside of function              
2989                 if ( (callTarget < firstAddress) || 
2990                      (callTarget > firstAddress + size()) ) { 
2991
2992                   // get target instruction
2993                   instruction tmpInsn;
2994                   tmpInsn.raw = owner->get_instruction(callTarget - baseAddress);
2995                   // If call target instruction is a retl instruction
2996                   if((tmpInsn.raw & 0xfffff000) == 0x81c3e000) {
2997
2998                     // Retrieve the instruction in the delay slot of the retl,
2999                     // so that it can be copied into the relocated function
3000                     tmpInsn.raw = 
3001                     owner->get_instruction( (callTarget - baseAddress) + sizeof(instruction) );
3002
3003                     RetlSetO7 *retlSetO7 = 
3004                         new RetlSetO7(this, i * sizeof(instruction), tmpInsn);
3005                     p->AddAlteration(retlSetO7);
3006
3007 #ifdef DEBUG_PA_INST
3008                     cerr << " detected call to retl instruction"
3009                          << " designed to set 07 register at offset " 
3010                          <<  i * sizeof(instruction) << endl;
3011 #endif
3012                   }
3013                 }
3014             }
3015         }
3016     }
3017
3018     // Look for an instPoint in funcCalls where the instruction is 
3019     //  a call instruction and the next instruction is a restore op
3020     //  or where the instruction is a jmp (out of function?), and the next 
3021     //  instruction is a nop....
3022     // There is an unfortunate dependence on the method for detecting tail-call
3023     //  optimizations in the code for detecting overlapping inst-points, below.
3024     //  If change this code, may need to update that code correspondingly....
3025     for(unsigned i=0;i<calls.size();i++) {
3026         // this should return the offset at which the FIRST instruction which
3027         //  is ACTUALLY OVEWRITTEN BY INST POINT is located....
3028         the_call = calls[i];
3029         int offset = (the_call->iPgetAddress() - getAddress(0));
3030         instr = the_call->insnAtPoint();
3031         nexti = the_call->insnAfterPoint();
3032         if (CallRestoreTC(instr, nexti)) {
3033             tail_call = new CallRestoreTailCallOptimization(this, offset, 
3034                                    offset + 2 * sizeof(instruction), instr);
3035             p->AddAlteration(tail_call);
3036 #ifdef DEBUG_PA_INST
3037             cerr << " detected call, restore tail-call optimization at offset " 
3038                  << offset << endl;
3039 #endif
3040         }
3041         if (JmpNopTC(instr, nexti, the_call->iPgetAddress(), this)) {
3042             tail_call = new JmpNopTailCallOptimization(this, offset, 
3043                                    offset + 2 * sizeof(instruction));
3044             p->AddAlteration(tail_call);
3045 #ifdef DEBUG_PA_INST
3046             cerr << " detected jmp, nop tail-call optimization at offset " 
3047                  << offset << endl;
3048 #endif
3049         }
3050     }
3051
3052     return true;
3053 }
3054
3055 /****************************************************************************/
3056 /****************************************************************************/
3057 /****************************************************************************/
3058
3059 /* 
3060   Second pass, handle cases where inst points overlap eachother (and
3061   thus prevent the normal instrumentation technique from being used).
3062     In current sparc-solaris version, the following algorithm is used:
3063      Check all inst points.  If any overlap, figure out the instruction
3064      that each is trying to get and insert nops so that they no longer
3065      overlap.  
3066 */
3067 bool pd_Function::PA_attachOverlappingInstPoints(
3068                         LocalAlterationSet *p, Address /* baseAddress */, 
3069                         Address /* firstAddress */,
3070                         instruction loadedCode[], int /* codeSize */) {
3071
3072     instruction instr, nexti;
3073
3074 #ifdef DEBUG_PA_INST
3075     cerr << "pd_Function::PA_attachOverlappingInstPoints called" <<endl;
3076     cerr << " prettyName = " << prettyName() << endl;
3077 #endif
3078
3079     // Make a list of all inst-points attached to function, and sort
3080     //  by address.  Then check for overlaps....
3081     vector<instPoint*> foo;
3082     //foo += funcEntry_;
3083     //foo += funcReturns;
3084     //foo += calls;
3085     // define sort_inst_points_by_address as function with following
3086     //  interface:
3087     //  void             sort (int (*)(const void *, const void *))
3088     //   - takes 2 void *'s, typecasts to instPoint *'s, then does
3089     //   {-1, 0, 1} comparison based on ip->addr....
3090     // foo.sort(sort_inst_points_by_address);
3091     // qsort((void *) data_, sz_, sizeof(T), cmpfunc);
3092     //qsort(foo.data(), foo.size(), sizeof(instPoint*), sort_inst_points_by_address);
3093     
3094     sorted_ips_vector(foo);
3095
3096     // should hopefully have inst points for fn sorted by address....
3097     // check for overlaps....
3098     for (unsigned i=0;i<foo.size()-1;i++) {
3099         instPoint *this_inst_point = foo[i];
3100         instPoint *next_inst_point = foo[i+1];
3101         // This is kind of a hack - strictly speaking, the peephole alteration 
3102         //  abstraction for relocating inst points should be applied to the set of
3103         //  inst points in the function after every independent set of alterations is
3104         //  applied.  This is nto done for performance reasons - rather all the inst
3105         //  points in the function are relocated at once - based on the alteration sets.
3106         // As such, the peephole alterations are NOT implemented so as to be strictly
3107         //  independent.  An example of this is the interaction of the code for attaching
3108         //  tail-call optimization PAs based on inst points (NOT function instructions),
3109         //  above.  Anyway, the net efffect is that by the time flow-of-control reaches 
3110         //  here, the tail-call optimization has (hopefully) been rewritten, but the 
3111         //  inst points pointing to it have not been updated.  As such, check here to
3112         //  make sure that the overalpping inst points aren't really part of a tail-call
3113         //  optimization.  This introduces some lack of locality of reference - sorry....
3114         
3115         if ((this_inst_point->ipType == callSite) && 
3116                   (next_inst_point->ipType == functionExit)) {
3117           instr = this_inst_point->insnAtPoint();
3118           nexti = this_inst_point->insnAfterPoint();
3119           if (CallRestoreTC(instr, nexti) || 
3120             JmpNopTC(instr, nexti, this_inst_point->iPgetAddress(), this)) {
3121
3122              // This tail call optimization will be rewritten, eliminating the
3123              // overlap, so we don't have to worry here about rewriting this
3124              // as overlapping instPoints.
3125              // Also, I added the i++ because we don't have to bother looking 
3126              // for an overlap between the next_inst_point, and any instPoints 
3127              // that may follow it (even one that is located at the very next 
3128              // instruction). The reason for this is that when we relocate the 
3129              // function, we will call installBaseTrampSpecial to generate the
3130              // base tramp. The distance between the base tramp and the 
3131              // relocated function will then be within the range
3132              // of a branch insn, and only one instruction at the instPoint 
3133              // will be relocated to the baseTramp (since the restore or nop
3134              // will not also have a delay slot insn) which means that there 
3135              // will be no conflict with next_inst_point overlapping another
3136              // instPoint.  itai 
3137              i++;
3138
3139              continue;
3140           }
3141         }
3142
3143         // check if inst point overlaps with next inst point....
3144         int overlap = ((this_inst_point->iPgetAddress() + 
3145           this_inst_point->Size()) - next_inst_point->iPgetAddress());
3146         if (overlap > 0) {
3147             // Inst point overlaps with next one.  Insert 
3148             //  InsertNops into PA Set AFTER instruction pointed to
3149             //  by inst point (Making sure that this does NOT break up 
3150             //  an insn and its delay slot).....
3151             // ALRT ALRT : This is NOT designed to handle the case where
3152             //  2 inst points are located at exactly the same place or 
3153             //  1 is located in the delay slot of the other - it will NOT
3154             //  break up the 2 inst points in that case....
3155
3156             int offset = (this_inst_point->insnAddress() - getAddress(0));
3157             
3158             if (IS_DELAYED_INST(loadedCode[offset/sizeof(instruction)])) {
3159               offset += sizeof(instruction);
3160             } 
3161             InsertNops *nops = new InsertNops(this, offset, overlap);
3162             p->AddAlteration(nops);
3163
3164 #ifdef DEBUG_PA_INST
3165             cerr << " detected overlapping inst points : offset " << offset <<
3166               " overlap " << overlap << endl;
3167 #endif
3168         }
3169     }
3170     return true;
3171 }
3172
3173 /****************************************************************************/
3174 /****************************************************************************/
3175 /****************************************************************************/
3176
3177 /*
3178   Third pass, handle cases where inst points overlap branch/jump targets.
3179     In current sparc-solaris version, the following algorithm is used:
3180      Check all branch/jump operations.  If they go into footprint of 
3181      any inst points, then try to insert nops so that the branch targets
3182      move outside of the the footprint....
3183   Note that the algorithm given below should be attached AFTER alterations
3184    which unwind tail-call optimizations and seperate overlapping inst points
3185    have been BOTH attached and applied....
3186  */
3187 bool pd_Function::PA_attachBranchOverlaps(
3188                              LocalAlterationSet *p, Address /* baseAddress */, 
3189                              Address firstAddress, instruction loadedCode[],
3190                              unsigned /* numberOfInstructions */, 
3191                              int codeSize)  {
3192
3193 #ifdef DEBUG_PA_INST
3194     cerr << "pd_Function::PA_attachBranchOverlaps called" <<endl;
3195     cerr << " prettyName = " << prettyName() << endl;
3196 #endif
3197
3198     // Make a list of all inst-points attached to function, and sort
3199     //  by address.  Then check for overlaps....
3200     vector<instPoint*> foo;
3201     foo.push_back(funcEntry_);
3202     VECTOR_APPEND(foo,funcReturns);
3203     VECTOR_APPEND(foo,calls);
3204
3205     // Sort inst points list by address....
3206     VECTOR_SORT(foo, sort_inst_points_by_address);
3207
3208     // Iterate over function instruction by instruction....
3209     assert((codeSize % sizeof(instruction)) == 0);
3210     for(unsigned i=0;i<(codeSize/sizeof(instruction));i++) {
3211         // looking for branch instructions inside function....
3212         if (!branchInsideRange(loadedCode[i], 
3213                                firstAddress + (i * sizeof(instruction)),
3214                                firstAddress, 
3215                                firstAddress + size())) {
3216             continue;
3217         }
3218                                                               
3219         int disp = loadedCode[i].branch.disp22;
3220         Address target = firstAddress + (i * sizeof(instruction))
3221                                                             + (disp << 2);
3222
3223         // branch insn inside function.  Check target versus known inst points....
3224         instPoint *overlap = find_overlap(foo, target);
3225         if (overlap == NULL) continue;
3226
3227         //
3228         // ALRT ALRT - What happens if you have multiple barcnhes to the same spot?
3229         //  They will reuslt in multiple identical NOP expansions added here.  Need
3230         //  LocalAlterationSet to ignore multiple identical alterations (identical
3231         //  in type, location, and all fields) beyond first....
3232         //
3233         // branch target inside function and inside inst point footprint....
3234         //  if target is before actual inst point target instruction, add
3235         //  (target - 1st addres) nops, where 1st address is address of 1st
3236         //  instruction actually inside the footprint....
3237         if (target <= overlap->iPgetAddress()) {
3238             InsertNops *nops = new InsertNops(this, 
3239                                (target - firstAddress) - sizeof(instruction), 
3240                                target - overlap->firstAddress());
3241             p->AddAlteration(nops);
3242 #ifdef DEBUG_PA_INST
3243             cerr << " detected overlap between branch target and inst point : offset "
3244                  << target - firstAddress << " # bytes " 
3245                  << target - overlap->firstAddress() << endl;
3246 #endif