Fixed demangling of names in Windows (we weren't always stripping off
[dyninst.git] / dyninstAPI / src / inst-x86.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 /*
43  * inst-x86.C - x86 dependent functions and code generator
44  * $Id: inst-x86.C,v 1.122 2003/03/13 00:47:55 buck Exp $
45  */
46
47 #include <iomanip.h>
48
49 #include <limits.h>
50 #include "common/h/headers.h"
51
52 #ifndef BPATCH_LIBRARY
53 #include "rtinst/h/rtinst.h"
54 #endif
55 #include "common/h/Dictionary.h"
56 #include "dyninstAPI/src/symtab.h"
57 #include "dyninstAPI/src/process.h"
58 #include "dyninstAPI/src/dyn_lwp.h"
59 #include "dyninstAPI/src/inst.h"
60 #include "dyninstAPI/src/instP.h"
61 #include "dyninstAPI/src/ast.h"
62 #include "dyninstAPI/src/util.h"
63 #include "dyninstAPI/src/stats.h"
64 #include "dyninstAPI/src/os.h"
65 #include "dyninstAPI/src/showerror.h"
66
67 #include "dyninstAPI/src/arch-x86.h"
68 #include "dyninstAPI/src/inst-x86.h"
69 #include "dyninstAPI/src/instPoint.h" // includes instPoint-x86.h
70 #include "dyninstAPI/src/instP.h" // class returnInstance
71 #include "dyninstAPI/src/rpcMgr.h"
72
73 // for function relocation
74 #include "dyninstAPI/src/func-reloc.h" 
75 #include "dyninstAPI/src/LocalAlteration.h"
76
77 class ExpandInstruction;
78 class InsertNops;
79
80 extern bool relocateFunction(process *proc, instPoint *&location);
81 extern void modifyInstPoint(instPoint *&location,process *proc);
82
83 extern bool isPowerOf2(int value, int &result);
84 void BaseTrampTrapHandler(int); //siginfo_t*, ucontext_t*);
85
86
87 // The general machine registers. 
88 // These values are taken from the Pentium manual and CANNOT be changed.
89 #undef EAX 
90 #define EAX (0)
91 #undef ECX
92 #define ECX (1)
93 #undef EDX
94 #define EDX (2)
95 #undef EBX
96 #define EBX (3)
97 #undef ESP
98 #define ESP (4)
99 #undef EBP
100 #define EBP (5)
101 #undef ESI
102 #define ESI (6)
103 #undef EDI
104 #define EDI (7)
105
106 // Size of a jump rel32 instruction
107 #define JUMP_REL32_SZ (5)
108 #define JUMP_SZ (5)
109 // Size of a call rel32 instruction
110 #define CALL_REL32_SZ (5)
111
112 #define PUSH_RM_OPC1 (0xFF)
113 #define PUSH_RM_OPC2 (6)
114 #define CALL_RM_OPC1 (0xFF)
115 #define CALL_RM_OPC2 (2)
116 #define PUSH_EBP (0x50+EBP)
117 #define SUB_REG_IMM32 (5)
118 #define LEAVE (0xC9)
119
120 /*
121    Function arguments are in the stack and are addressed with a displacement
122    from EBP. EBP points to the saved EBP, EBP+4 is the saved return address,
123    EBP+8 is the first parameter.
124    TODO: what about far calls?
125  */
126
127 #define FUNC_PARAM_OFFSET (8+(9*4))
128 #define CALLSITE_PARAM_OFFSET (4+(9*4))
129
130
131 // number of virtual registers
132 #define NUM_VIRTUAL_REGISTERS (32)
133
134 // offset from EBP of the saved EAX for a tramp
135 #define SAVED_EAX_OFFSET (9*4-4)
136 #define SAVED_EFLAGS_OFFSET (SAVED_EAX_OFFSET+4)
137
138 /****************************************************************************/
139 /****************************************************************************/
140 /****************************************************************************/
141
142 class NonRecursiveTrampTemplate : public trampTemplate
143 {
144
145 public:
146
147   int guardOnPre_beginOffset;
148   int guardOnPre_endOffset;
149
150   int guardOffPre_beginOffset;
151   int guardOffPre_endOffset;
152
153   int guardOnPost_beginOffset;
154   int guardOnPost_endOffset;
155
156   int guardOffPost_beginOffset;
157   int guardOffPost_endOffset;
158
159 };
160
161 /****************************************************************************/
162 /****************************************************************************/
163 /****************************************************************************/
164
165 static void emitOpRMImm8( unsigned opcode1, unsigned opcode2, Register base, int disp, char imm,
166                           unsigned char * & insn );
167 static void emitMovImmToMem( Address maddr, int imm,
168                              unsigned char * & insn );
169
170 /****************************************************************************/
171 /****************************************************************************/
172 /****************************************************************************/
173
174 /*
175    checkInstructions: check that there are no known jumps to the instructions
176    before and after the point.
177 */
178 void instPoint::checkInstructions() {
179   Address currAddr = addr_;
180   unsigned OKinsns = 0;
181
182   // if jumpAddr_ is not zero, this point has been checked already
183   if (jumpAddr_) 
184     return;
185
186   unsigned tSize;
187   unsigned maxSize = JUMP_SZ;
188   if (address() == func()->getAddress(0)) // entry point
189     maxSize = 2*JUMP_SZ;
190   tSize = insnAtPoint_.size();
191
192   if (!owner()->isJumpTarget(currAddr)) {
193     // check instructions before point
194     unsigned insnsBefore_ = insnsBefore();
195     for (unsigned u = 0; u < insnsBefore_; u++) {
196       OKinsns++;
197       tSize += (*insnBeforePt_)[u].size();
198       currAddr -= (*insnBeforePt_)[u].size();
199       if (owner()->isJumpTarget(currAddr)) {
200         // must remove instruction from point
201         // fprintf(stderr, "check instructions point 0x%lx, jmp to 0x%lx\n",
202         //                addr,currAddr);
203         break;
204       }
205     }
206   }
207   if (insnBeforePt_)
208     (*insnBeforePt_).resize(OKinsns);
209
210   // this is the address where we insert the jump
211   jumpAddr_ = currAddr;
212
213   // check instructions after point
214   currAddr = addr_ + insnAtPoint_.size();
215   OKinsns = 0;
216   unsigned insnsAfter_ = insnsAfter();
217   for (unsigned u = 0; tSize < maxSize && u < insnsAfter_; u++) {
218     if (owner()->isJumpTarget(currAddr))
219       break;
220     OKinsns++;
221     unsigned size = (*insnAfterPt_)[u].size();
222     currAddr += size;
223     tSize += size;
224   }
225   if (insnAfterPt_)
226     (*insnAfterPt_).resize(OKinsns);
227   
228 #ifdef notdef
229   if (tSize < maxSize) {
230     tSize = insnAtPoint_.size();
231     jumpAddr_ = addr_;
232     if (insnBeforePt_) (*insnBeforePt_).resize(0);
233     if (insnAfterPt_) (*insnAfterPt_).resize(0);
234   }
235 #endif
236 }
237
238 /* PT is an instrumentation point.  ENTRY is the entry point for the
239    same function, and EXITS are the exit instrumentation points for
240    the function.  Returns true if this function supports an extra slot
241    and PT can use it. */
242 static bool
243 _canUseExtraSlot(const instPoint *pt, const instPoint *entry,
244                  const pdvector<instPoint*> &exits)
245 {
246      if (entry->size() < 2*JUMP_SZ)
247           return false;
248
249      // We get 10 bytes for the entry points, instead of the usual five,
250      // so that we have space for an extra jump. We can then insert a
251      // jump to the basetramp in the second slot of the base tramp
252      // and use a short 2-byte jump from the point to the second jump.
253      // We adopt the following rule: Only one point in the function
254      // can use the indirect jump, and this is the first return point
255      // with a size that is less than five bytes
256      bool canUse = false;
257      for (unsigned u = 0; u < exits.size(); u++)
258           if (exits[u] == pt) {
259                canUse = true;
260                break;
261           } else if (exits[u]->size() < JUMP_SZ)
262                return false;
263      if (!canUse)
264           return false;
265
266      /* The entry has a slot, the point can be used for a slot,
267         now see if the point can reach the slot. */
268      int displacement = entry->jumpAddr() + 5 - pt->jumpAddr();
269      assert(displacement < 0);
270      if (pt->size() >= 2 && (displacement-2) > SCHAR_MIN)
271           return true;
272      else
273           return false;
274 }
275
276 /*
277    Returns true if we can use the extra slot for a jump at the entry point
278    to insert a jump to a base tramp at this point.  */
279 bool instPoint::canUseExtraSlot(process *proc) const
280 {
281      return _canUseExtraSlot(this,
282                              func()->funcEntry(proc),
283                              func()->funcExits(proc));
284 }
285
286 /* ENTRY and EXITS are the entry and exit points of a function.  PT
287    must be a point in the same function.  Return true if PT requires a
288    trap to instrument. */
289 static bool
290 _usesTrap(const instPoint *pt,
291           const instPoint *entry,
292           const pdvector<instPoint*> &exits)
293 {
294      /* If this point is big enough to hold a 32-bit jump to any
295         basetramp, it doesn't need a trap. */
296      if (pt->size() >= JUMP_REL32_SZ)
297           return false;
298
299      /* If it can use the extra slot, it doesn't need a trap. */
300      if (_canUseExtraSlot(pt, entry, exits)) {
301           return false;
302      }
303      /* Otherwise it needs a trap. */
304      return true;
305 }
306
307 bool instPoint::usesTrap(process *proc) const
308 {
309      return _usesTrap(this, func()->funcEntry(proc), func()->funcExits(proc));
310 }
311
312 /**************************************************************
313  *
314  *  machine dependent methods of pdFunction
315  *
316  **************************************************************/
317
318 // Determine if the called function is a "library" function or a "user" function
319 // This cannot be done until all of the functions have been seen, verified, and
320 // classified
321 //
322 void pd_Function::checkCallPoints() {
323   unsigned int i;
324   instPoint *p;
325   Address loc_addr;
326
327   pdvector<instPoint*> non_lib;
328
329   for (i=0; i<calls.size(); ++i) {
330     /* check to see where we are calling */
331     p = calls[i];
332     assert(p);
333
334     if (!p->insnAtPoint().isCallIndir()) {
335       loc_addr = p->insnAtPoint().getTarget(p->address());
336       file()->exec()->addJumpTarget(loc_addr);
337       pd_Function *pdf = (file_->exec())->findFuncByAddr(loc_addr);
338
339       if (pdf) {
340         p->set_callee(pdf);
341         non_lib.push_back(p);
342       } else {
343            // if this is a call outside the fuction, keep it
344            if((loc_addr < getAddress(0))||(loc_addr > (getAddress(0)+size()))){
345                 non_lib.push_back(p);
346            }
347            else {
348                delete p;
349            }
350       } 
351     } else {
352       // Indirect call -- be conservative, assume it is a call to
353       // an unnamed user function
354       //assert(!p->callee());
355       p->set_callee(NULL);
356       non_lib.push_back(p);
357     }
358   }
359   calls = non_lib;
360
361 }
362
363 // this function is not needed
364 Address pd_Function::newCallPoint(Address, const instruction,
365                                  const image *, bool &)
366 { assert(0); return 0; }
367
368
369 // see if we can recognize a jump table and skip it
370 // return the size of the table in tableSz.
371 bool checkJumpTable(image *im, instruction insn, Address addr, 
372                     Address funcBegin, 
373                     Address &funcEnd,
374                     unsigned &tableSz) {
375
376   const unsigned char *instr = insn.ptr();
377   tableSz = 0;
378   /*
379      the instruction usually used for jump tables is 
380        jmp dword ptr [REG*4 + ADDR]
381      where ADDR is an immediate following the SIB byte.
382      The opcode is 0xFF and the MOD/RM byte is 0x24. 
383      The SS field (bits 7 and 6) of SIB is 2, and the
384      base ( bits 2, 1, 0) is 5. The index bits (5,4,3) 
385      select the register.
386   */
387   if (instr[0] == 0xFF && instr[1] == 0x24 &&
388       ((instr[2] & 0xC0)>>6) == 2 && (instr[2] & 0x7) == 5) {
389     const Address tableBase = *(const Address *)(instr+3);
390     //fprintf(stderr, "Found jump table at 0x%lx 0x%lx\n",addr, tableBase);
391     // check if the table is right after the jump and inside the current function
392     if (tableBase > funcBegin && tableBase < funcEnd) {
393       // table is within function code
394       if (tableBase < addr+insn.size()) {
395         fprintf(stderr, "bad indirect jump at 0x%lx\n", addr);
396         return false;
397       } else if (tableBase > addr+insn.size()) {
398         // jump table may be at the end of the function code - adjust funcEnd
399         funcEnd = tableBase;
400         return true;
401       }
402       // skip the jump table
403       for (const unsigned *ptr = (const unsigned *)im->getPtrToInstruction(tableBase);
404            *ptr >= funcBegin && *ptr <= funcEnd; ptr++) {
405         //fprintf(stderr, " jump table entry = 0x%lx\n", *(unsigned *)ptr);
406         tableSz += sizeof(int);
407       }
408     }
409     else {
410         // fprintf(stderr, "Ignoring external jump table at 0x%lx.\n", tableBase);
411     }
412   }
413   return true;
414 }
415
416 void checkIfRelocatable(instruction insn, bool &canBeRelocated) {
417   const unsigned char *instr = insn.ptr();
418
419   // Check if REG bits of ModR/M byte are 100 or 101 (Possible jump 
420   // to jump table).
421   if (instr[0] == 0xFF && 
422      ( ((instr[1] & 0x38)>>3) == 4 || ((instr[1] & 0x38)>>3) == 5 )) {
423
424     // function should not be relocated
425     canBeRelocated = false;
426   }
427 }
428
429
430 bool isRealCall(instruction &insn, Address adr, image *owner, bool &validTarget, pd_Function *pdf) {
431
432   // calls to adr+5 are not really calls, they are used in 
433   // dynamically linked libraries to get the address of the code.
434   if (insn.getTarget(adr) == adr + 5) {
435     return false;
436   }
437
438
439   // Calls to a mov instruction followed by a ret instruction, where the 
440   // source of the mov is the %esp register, are not real calls.
441   // These sequences are used to set the destination register of the mov 
442   // with the pc of the instruction instruction that follows the call.
443
444   // This sequence accomplishes this because the call instruction has the 
445   // side effect of placing the value of the %eip on the stack and setting the
446   // %esp register to point to that location on the stack. (The %eip register
447   // maintains the address of the next instruction to be executed).
448   // Thus, when the value at the location pointed to by the %esp register 
449   // is moved, the destination of the mov is set with the pc of the next
450   // instruction after the call.   
451
452   //    Here is an example of this sequence:
453   //
454   //       mov    %esp, %ebx
455   //       ret    
456   //
457   //    These two instructions are specified by the bytes 0xc3241c8b
458   //
459
460   int targetAdr = insn.getTarget(adr);
461  
462   if ( !owner->isValidAddress(targetAdr) ) {
463     validTarget = false;
464     return false;
465   }    
466
467   // Get a pointer to the call target
468   const unsigned char *target = (const unsigned char *)owner->getPtrToInstruction(targetAdr);
469
470   // The target instruction is a  mov
471   if (*(target) == 0x8b) {
472
473     // The source register of the mov is specified by a SIB byte 
474     if (*(target + 1) == 0x1c) {
475
476       // The source register of the mov is the %esp register (0x24) and 
477       // the instruction after the mov is a ret instruction (0xc3)
478       if ( (*(target + 2) == 0x24) && (*(target + 3) == 0xc3)) {
479         return false;
480       }
481     }
482   }
483
484   return true;
485 }
486
487
488 /* auxiliary data structures for function findInstPoints */
489 enum { EntryPt, CallPt, ReturnPt, OtherPt };
490 class point_ {
491   public:
492      point_(): point(0), index(0), type(0) {};
493      point_(instPoint *p, unsigned i, unsigned t): point(p), index(i), type(t) {};
494      instPoint *point;
495      unsigned index;
496      unsigned type;
497 };
498
499
500 bool pd_Function::findInstPoints(const image *i_owner) {
501    // sorry this this hack, but this routine can modify the image passed in,
502    // which doesn't occur on other platforms --ari
503    image *owner = const_cast<image *>(i_owner); // const cast
504
505    if (size() == 0) {
506       //fprintf(stderr,"Function %s, size = %d\n", prettyName().c_str(), size());
507       return false;
508    }
509
510 #if defined(i386_unknown_solaris2_5)
511    /* On Solaris, this function is called when a signal handler
512       returns.  If it requires trap-based instrumentation, it can foul
513       the handler return mechanism.  So, better exclude it.  */
514    if (prettyName() == "_setcontext" || prettyName() == "setcontext")
515       return false;
516 #endif /* i386_unknown_solaris2_5 */
517
518    // XXXXX kludge: these functions are called by DYNINSTgetCPUtime, 
519    // they can't be instrumented or we would have an infinite loop
520    if (prettyName() == "gethrvtime" || prettyName() == "_divdi3"
521        || prettyName() == "GetProcessTimes")
522       return false;
523
524    point_ *points = new point_[size()];
525    //point_ *points = (point_ *)alloca(size()*sizeof(point));
526    unsigned npoints = 0;
527
528    const unsigned char *instr = (const unsigned char *)owner->getPtrToInstruction(getAddress(0));
529    Address adr = getAddress(0);
530    unsigned numInsns = 0;
531
532    instruction insn;
533    unsigned insnSize;
534
535    // keep a buffer with all the instructions in this function
536    instruction *allInstr = new instruction[size()+5];
537    //instruction *allInstr = (instruction *)alloca((size()+5)*sizeof(instruction));
538
539    // define the entry point
540    insnSize = insn.getNextInstruction(instr);
541    instPoint *p = new instPoint(this, owner, adr, functionEntry, insn);
542    funcEntry_ = p;
543    points[npoints++] = point_(p, numInsns, EntryPt);
544
545    // check if the entry point contains another point
546    if (insn.isJumpDir()) {
547       Address target = insn.getTarget(adr);
548       owner->addJumpTarget(target);
549       if (target < getAddress(0) || target >= getAddress(0) + size()) {
550          // jump out of function
551          // this is an empty function
552          delete [] points;
553          delete [] allInstr;
554          return false;
555       }
556    } else if (insn.isReturn()) {
557       // this is an empty function
558       delete [] points;
559       delete [] allInstr;
560       return false;
561    } else if (insn.isCall()) {
562       // TODO: handle calls at entry point
563       // call at entry point
564       //instPoint *p = new instPoint(this, owner, adr, functionEntr, insn);
565       //calls += p;
566       //points[npoints++] = point_(p, numInsns, CallPt);
567       //fprintf(stderr,"Function %s, call at entry point\n", prettyName().c_str());
568
569       delete [] points;
570       delete [] allInstr;
571       return false;
572    }
573
574    allInstr[numInsns] = insn;
575    numInsns++;
576    instr += insnSize;
577    adr += insnSize;
578
579    // get all the instructions for this function, and define the
580    // instrumentation points. For now, we only add one instruction to each
581    // point.  Additional instructions, for the points that need them, will be
582    // added later.
583
584 #ifdef BPATCH_LIBRARY
585    if (BPatch::bpatch->hasForcedRelocation_NP()) {
586       relocatable_ = true;
587    }
588 #endif
589
590    // checkJumpTable will set canBeRelocated = false if their is a jump to a 
591    // jump table inside this function. 
592    bool canBeRelocated = true;
593
594    if (prettyName() == "__libc_fork" || prettyName() == "__libc_start_main") {
595       canBeRelocated = false;
596    }
597
598    Address funcEnd = getAddress(0) + size();
599    for ( ; adr < funcEnd; instr += insnSize, adr += insnSize) {
600
601       insnSize = insn.getNextInstruction(instr);
602
603       assert(insnSize > 0);
604
605       if (adr + insnSize > funcEnd) {
606          break;
607       }
608
609       if (insn.isJumpIndir()) {
610          unsigned jumpTableSz;
611
612          // check if function should be allowed to be relocated
613          checkIfRelocatable(insn, canBeRelocated);
614
615          // check for jump table. This may update funcEnd
616          if (!checkJumpTable(owner, insn, adr, getAddress(0), funcEnd, jumpTableSz)) {
617             delete points;
618             delete allInstr;
619             //fprintf(stderr,"Function %s, size = %d, bad jump table\n", 
620             //          prettyName().c_str(), size());
621             return false;
622          }
623
624          // process the jump instruction
625          allInstr[numInsns] = insn;
626          numInsns++;
627
628          if (jumpTableSz > 0) {
629             // skip the jump table
630             // insert an illegal instruction with the size of the jump table
631             insn = instruction(instr, ILLEGAL, jumpTableSz);
632             allInstr[numInsns] = insn;
633             numInsns++;
634             insnSize += jumpTableSz;
635          }
636       } else if (insn.isJumpDir()) {
637          // check for jumps out of this function
638          Address target = insn.getTarget(adr);
639          owner->addJumpTarget(target);
640          if (target < getAddress(0) || target >= getAddress(0) + size()) {
641             // jump out of function
642             instPoint *p = new instPoint(this, owner, adr, functionExit, insn);
643             funcReturns.push_back(p);
644             points[npoints++] = point_(p, numInsns, ReturnPt);
645          } 
646       } else if (insn.isReturn()) {
647
648          instPoint *p = new instPoint(this, owner, adr, functionExit, insn);
649          funcReturns.push_back(p);
650          points[npoints++] = point_(p, numInsns, ReturnPt);
651
652       } else if (insn.isCall()) {
653
654          // validTarget is set to false if the call target is not a valid 
655          // address in the applications process space 
656          bool validTarget = true;
657
658          if ( isRealCall(insn, adr, owner, validTarget, this) ) {
659             instPoint *p = new instPoint(this, owner, adr, callSite, insn);
660             calls.push_back(p);
661             points[npoints++] = point_(p, numInsns, CallPt);
662          } else {
663
664             // Call was to an invalid address, do not instrument function 
665             if (validTarget == false) {
666                delete [] points;
667                delete [] allInstr;
668                return false;
669             }
670
671             // Force relocation when instrumenting function
672             relocatable_ = true;
673          }
674       }
675
676       allInstr[numInsns] = insn;
677       numInsns++;
678       assert(npoints < size());
679       assert(numInsns <= size());
680    }
681
682
683    unsigned u;
684    // there are often nops after the end of the function. We get them here,
685    // since they may be usefull to instrument the return point
686    for (u = 0; u < 4; u++) {
687      
688       if (owner->isValidAddress(adr)) {
689          insnSize = insn.getNextInstruction(instr);
690          if (insn.isNop()) {
691             allInstr[numInsns] = insn;
692             numInsns++;
693             assert(numInsns < size()+5);
694             instr += insnSize;
695             adr += insnSize;
696          }
697          else
698             break;
699       }
700    }
701
702    // add extra instructions to the points that need it.
703    unsigned lastPointEnd = 0;
704    unsigned thisPointEnd = 0;
705    for (u = 0; u < npoints; u++) {
706       instPoint *p = points[u].point;
707       unsigned index = points[u].index;
708       unsigned type = points[u].type;
709       lastPointEnd = thisPointEnd;
710       thisPointEnd = index;
711
712       // add instructions before the point
713       unsigned size = p->size();
714       for (int u1 = index-1; size < JUMP_SZ && u1 >= 0 && u1 > (int)lastPointEnd; u1--) {
715          if (!allInstr[u1].isCall()) {
716             p->addInstrBeforePt(allInstr[u1]);
717             size += allInstr[u1].size();
718          } else
719             break;
720       }
721
722       lastPointEnd = index;
723
724       // add instructions after the point
725       if (type == ReturnPt && p->address() == funcEnd-1) {
726
727          /* If an instrumentation point at the end of the function does
728             not end on a 4-byte boundary, we claim the bytes up to the
729             next 4-byte boundary as "bonus bytes" for the point, since
730             the next function will (should) begin at or past the
731             boundary.  We tried 8 byte boundaries and found some
732             functions did not begin on 8-byte aligned addresses, so 8 is
733             unsafe. */
734          unsigned bonus;
735 #ifndef i386_unknown_nt4_0
736          bonus = (funcEnd % 4) ? (4 - (funcEnd % 4)) : 0;
737 #else
738          /* Unfortunately, the Visual C++ compiler generates functions
739             that begin at unaligned boundaries, so forget this scheme on
740             NT. */
741          bonus = 0;
742 #endif /* i386_unknown_nt4_0 */
743        //p->setBonusBytes(bonus);
744          unsigned u1;
745          for (u1 = index+1 + bonus; u1 < index+JUMP_SZ-1 && u1 < numInsns; u1++) {
746             if (allInstr[u1].isNop() || *(allInstr[u1].ptr()) == 0xCC) {
747                //p->addInstrAfterPt(allInstr[u1]);
748                bonus++;
749                thisPointEnd = u1;
750             }
751             else 
752                break;
753          }
754          p->setBonusBytes(bonus);
755       } else if (type == ReturnPt) {
756          // normally, we would not add instructions after the return, but the 
757          // compilers often add nops after the return, and we can use them if necessary
758          for (unsigned u1 = index+1; u1 < index+JUMP_SZ-1 && u1 < numInsns; u1++) {
759             if (allInstr[u1].isNop() || *(allInstr[u1].ptr()) == 0xCC) {
760                p->addInstrAfterPt(allInstr[u1]);
761                thisPointEnd = u1;
762             }
763             else 
764                break;
765          }
766       } else {
767          size = p->size();
768          unsigned maxSize = JUMP_SZ;
769          if (type == EntryPt) maxSize = 2*JUMP_SZ;
770          for (unsigned u1 = index+1; size < maxSize && u1 <= numInsns; u1++) {
771             if (((u+1 == npoints) || (u+1 < npoints && points[u+1].index > u1))
772                 && !allInstr[u1].isCall()) {
773                p->addInstrAfterPt(allInstr[u1]);
774                size += allInstr[u1].size();
775                thisPointEnd = u1;
776             }
777             else 
778                break;
779          }
780       }
781    }
782
783
784    for (u = 0; u < npoints; u++)
785       points[u].point->checkInstructions();
786
787    // create and sort vector of instPoints
788    pdvector<instPoint*> foo;
789    sorted_ips_vector(foo);
790
791    for (unsigned i=0;i<foo.size();i++) {
792
793       if (_usesTrap(foo[i], funcEntry_, funcReturns) && size() >= 5) {
794          relocatable_ = true;
795       }
796    }
797
798    // if the function contains a jump to a jump table, we can't relocate
799    // the function 
800    if ( !canBeRelocated ) {
801
802       // Function would have needed relocation 
803       if (relocatable_ == true) {
804
805 #ifdef DEBUG_FUNC_RELOC      
806          cerr << prettyName() << endl;
807          cerr << "Jump Table: Can't relocate function" << endl;
808 #endif
809
810          relocatable_ = false;
811
812       }
813    }
814
815    delete [] points;
816    delete [] allInstr;
817
818    return true;
819 }
820
821
822 /*
823  * Given an instruction, relocate it to a new address, patching up
824  *   any relative addressing that is present.
825  * The instruction may need to be replaced with a different size instruction
826  * or with multiple instructions.
827  * Return the size of the new instruction(s)
828  */
829 unsigned relocateInstruction(instruction insn,
830                          int origAddr, int newAddr,
831                          unsigned char *&newInsn)
832 {
833   /* 
834      Relative address instructions need to be modified. The relative address
835      can be a 8, 16, or 32-byte displacement relative to the next instruction.
836      Since we are relocating the instruction to a different area, we have
837      to replace 8 and 16-byte displacements with 32-byte displacements.
838
839      All relative address instructions are one or two-byte opcode followed
840      by a displacement relative to the next instruction:
841
842        CALL rel16 / CALL rel32
843        Jcc rel8 / Jcc rel16 / Jcc rel32
844        JMP rel8 / JMP rel16 / JMP rel32
845
846      The only two-byte opcode instructions are the Jcc rel16/rel32,
847      all others have one byte opcode.
848
849      The instruction JCXZ/JECXZ rel8 does not have an equivalent with rel32
850      displacement. We must generate code to emulate this instruction:
851      
852        JCXZ rel8
853
854      becomes
855
856        A0: JCXZ 2 (jump to A4)
857        A2: JMP 5  (jump to A9)
858        A4: JMP rel32 (relocated displacement)
859        A9: ...
860
861   */
862
863   const unsigned char *origInsn = insn.ptr();
864   unsigned insnType = insn.type();
865   unsigned insnSz = insn.size();
866   unsigned char *first = newInsn;
867
868   int oldDisp;
869   int newDisp;
870
871   if (insnType & REL_B) {
872     /* replace with rel32 instruction, opcode is one byte. */
873     if (*origInsn == JCXZ) {
874       oldDisp = (int)*(const char *)(origInsn+1);
875       newDisp = (origAddr + 2) + oldDisp - (newAddr + 9);
876       *newInsn++ = *origInsn; *(newInsn++) = 2; // jcxz 2
877       *newInsn++ = 0xEB; *newInsn++ = 5;        // jmp 5
878       *newInsn++ = 0xE9;                        // jmp rel32
879       *((int *)newInsn) = newDisp;
880       newInsn += sizeof(int);
881     }
882     else {
883       unsigned newSz=UINT_MAX;
884       if (insnType & IS_JCC) {
885         /* Change a Jcc rel8 to Jcc rel32. 
886            Must generate a new opcode: a 0x0F followed by (old opcode + 16) */
887         unsigned char opcode = *origInsn++;
888         *newInsn++ = 0x0F;
889         *newInsn++ = opcode + 0x10;
890         newSz = 6;
891       }
892       else if (insnType & IS_JUMP) {
893         /* change opcode to 0xE9 */
894         origInsn++;
895         *newInsn++ = 0xE9;
896         newSz = 5;
897       }
898       assert(newSz!=UINT_MAX);
899       oldDisp = (int)*(const char *)origInsn;
900       newDisp = (origAddr + 2) + oldDisp - (newAddr + newSz);
901       *((int *)newInsn) = newDisp;
902       newInsn += sizeof(int);
903     }
904   }
905   else if (insnType & REL_W) {
906     /* Skip prefixes */
907     if (insnType & PREFIX_OPR)
908       origInsn++;
909     if (insnType & PREFIX_SEG)
910       origInsn++;
911     /* opcode is unchanged, just relocate the displacement */
912     if (*origInsn == (unsigned char)0x0F)
913       *newInsn++ = *origInsn++;
914     *newInsn++ = *origInsn++;
915     oldDisp = *((const short *)origInsn);
916     newDisp = (origAddr + 5) + oldDisp - (newAddr + 3);
917     *((int *)newInsn) = newDisp;
918     newInsn += sizeof(int);
919   } else if (insnType & REL_D) {
920     // Skip prefixes
921     unsigned nPrefixes = 0;
922     if (insnType & PREFIX_OPR)
923       nPrefixes++;
924     if (insnType & PREFIX_SEG)
925       nPrefixes++;
926     for (unsigned u = 0; u < nPrefixes; u++)
927       *newInsn++ = *origInsn++;
928
929     /* opcode is unchanged, just relocate the displacement */
930     if (*origInsn == 0x0F)
931       *newInsn++ = *origInsn++;
932     *newInsn++ = *origInsn++;
933     oldDisp = *((const int *)origInsn);
934     newDisp = (origAddr + insnSz) + oldDisp - (newAddr + insnSz);
935     *((int *)newInsn) = newDisp;
936     newInsn += sizeof(int);
937   }
938   else {
939     /* instruction is unchanged */
940     for (unsigned u = 0; u < insnSz; u++)
941       *newInsn++ = *origInsn++;
942   }
943
944   return (newInsn - first);
945 }
946
947
948 /*
949  * Relocate a conditional jump and change the target to newTarget.
950  * The new target must be within 128 bytes from the new address
951  * Size of instruction is unchanged.
952  * Returns the old target
953  */
954 unsigned changeConditionalJump(instruction insn,
955                          int origAddr, int newAddr, int newTargetAddr,
956                          unsigned char *&newInsn)
957 {
958
959   const unsigned char *origInsn = insn.ptr();
960   unsigned insnType = insn.type();
961   unsigned insnSz = insn.size();
962
963   int oldDisp=-1;
964   int newDisp;
965
966   if (insnType & REL_B) {
967     /* one byte opcode followed by displacement */
968     /* opcode is unchanged */
969     assert(insnSz==2);
970     *newInsn++ = *origInsn++;
971     oldDisp = (int)*(const char *)origInsn;
972     newDisp = newTargetAddr - (newAddr + insnSz);
973     *newInsn++ = (char)newDisp;
974   }
975   else if (insnType & REL_W) {
976     /* Skip prefixes */
977     if (insnType & PREFIX_OPR)
978       *newInsn++ = *origInsn++;
979     if (insnType & PREFIX_SEG)
980       *newInsn++ = *origInsn++;
981
982     assert(*origInsn==0x0F);
983     *newInsn++ = *origInsn++; // copy the 0x0F
984     *newInsn++ = *origInsn++; // second opcode byte
985
986     oldDisp = *((const short *)origInsn);
987     newDisp = newTargetAddr - (newAddr + insnSz);
988     *((short *)newInsn) = (short)newDisp;
989     newInsn += sizeof(short);
990   }
991   else if (insnType & REL_D) {
992     // Skip prefixes
993     if (insnType & PREFIX_OPR)
994       *newInsn++ = *origInsn++;
995     if (insnType & PREFIX_SEG)
996       *newInsn++ = *origInsn++;
997
998     assert(*origInsn==0x0F);
999     *newInsn++ = *origInsn++; // copy the 0x0F
1000     *newInsn++ = *origInsn++; // second opcode byte
1001
1002     oldDisp = *((const int *)origInsn);
1003     newDisp = newTargetAddr - (newAddr + insnSz);
1004     *((int *)newInsn) = (int)newDisp;
1005     newInsn += sizeof(int);
1006   }
1007
1008   assert (oldDisp!=-1);
1009   return (origAddr+insnSz+oldDisp);
1010 }
1011
1012
1013
1014 unsigned getRelocatedInstructionSz(instruction insn)
1015 {
1016   const unsigned char *origInsn = insn.ptr();
1017   unsigned insnType = insn.type();
1018   unsigned insnSz = insn.size();
1019
1020   if (insnType & REL_B) {
1021     if (*origInsn == JCXZ)
1022       return 9;
1023     else {
1024       if (insnType & IS_JCC)
1025         return 6;
1026       else if (insnType & IS_JUMP) {
1027         return 5;
1028       }
1029     }
1030   }
1031   else if (insnType & REL_W) {
1032     return insnSz + 2;
1033   }
1034   return insnSz;
1035 }
1036
1037
1038 registerSpace *regSpace;
1039
1040
1041 bool registerSpace::readOnlyRegister(Register) {
1042   return false;
1043 }
1044
1045 /*
1046    We don't use the machine registers to store temporaries,
1047    but "virtual registers" that are located on the stack.
1048    The stack frame for a tramp is:
1049
1050      ebp->    saved ebp (4 bytes)
1051      ebp-4:   128-byte space for 32 virtual registers (32*4 bytes)
1052      ebp-132: saved registers (8*4 bytes)
1053      ebp-164: saved flags registers (4 bytes)
1054
1055      The temporaries are assigned numbers from 1 so that it is easier
1056      to refer to them: -(reg*4)[ebp]. So the first reg is -4[ebp].
1057
1058      We are using a fixed number of temporaries now (32), but we could 
1059      change to using an arbitrary number.
1060
1061 */
1062 Register deadList[NUM_VIRTUAL_REGISTERS];
1063 int deadListSize = sizeof(deadList);
1064
1065 void initTramps()
1066 {
1067     static bool inited=false;
1068
1069     if (inited) return;
1070     inited = true;
1071
1072 #if defined(MT_THREAD)
1073     for (unsigned u = 0; u < NUM_VIRTUAL_REGISTERS-1; u++) {
1074 #else
1075     for (unsigned u = 0; u < NUM_VIRTUAL_REGISTERS; u++) {
1076 #endif
1077       deadList[u] = u+1;
1078     }
1079
1080     regSpace = new registerSpace(deadListSize/sizeof(Register), deadList,
1081                                 0, NULL);
1082 }
1083
1084
1085 static void emitJump(unsigned disp32, unsigned char *&insn);
1086 static void emitSimpleInsn(unsigned opcode, unsigned char *&insn);
1087 static void emitMovRegToReg(Register dest, Register src, unsigned char *&insn);
1088 static void emitAddMemImm32(Address dest, int imm, unsigned char *&insn);
1089 static void emitAddRegImm32(Register dest, int imm, unsigned char *&insn);
1090 static void emitOpRegImm(int opcode, Register dest, int imm, unsigned char *&insn);
1091 static void emitMovRegToRM(Register base, int disp, Register src, unsigned char *&insn);
1092 static void emitMovRMToReg(Register dest, Register base, int disp, unsigned char *&insn);
1093 void emitCallRel32(unsigned disp32, unsigned char *&insn); // XXX used by paradyn
1094 static void emitOpRegRM(unsigned opcode, Register dest, Register base, int disp,
1095                  unsigned char *&insn);
1096
1097
1098 /*
1099  * change the insn at addr to be a branch to newAddr.
1100  *   Used to add multiple tramps to a point.
1101  */
1102 void generateBranch(process *proc, Address fromAddr, Address newAddr)
1103 {
1104   unsigned char inst[JUMP_REL32_SZ+1];
1105   unsigned char *insn = inst;
1106   emitJump(newAddr - (fromAddr + JUMP_REL32_SZ), insn);
1107   proc->writeTextSpace((caddr_t)fromAddr, JUMP_REL32_SZ, (caddr_t)inst);
1108 }
1109
1110
1111 bool insertInTrampTable(process *proc, unsigned key, unsigned val) {
1112   unsigned u;
1113
1114   // check for overflow of the tramp table. 
1115   // stop at 95% capacicty to ensure good performance
1116   if (proc->trampTableItems == (TRAMPTABLESZ - TRAMPTABLESZ/20))
1117     return false;
1118   proc->trampTableItems++;
1119   for (u = HASH1(key); proc->trampTable[u].key != 0; 
1120        u = (u + HASH2(key)) % TRAMPTABLESZ)
1121     ;
1122   proc->trampTable[u].key = key;
1123   proc->trampTable[u].val = val;
1124
1125 #if !defined(i386_unknown_nt4_0)
1126   bool err = false;
1127   Address addr = proc->findInternalAddress("DYNINSTtrampTable",true, err);
1128   assert(err==false);
1129   return proc->writeDataSpace((caddr_t)addr+u*sizeof(trampTableEntry),
1130                        sizeof(trampTableEntry),
1131                        (caddr_t)&(proc->trampTable[u]));
1132 #else
1133   return true;
1134 #endif
1135 }
1136
1137 /* Generate a jump to a base tramp. Return the size of the instruction
1138    generated at the instrumentation point. */
1139 unsigned generateBranchToTramp(process *proc, const instPoint *point, 
1140                                Address baseAddr, Address imageBaseAddr,
1141                                unsigned char *insn, bool &deferred)
1142 {
1143      /* There are three ways to get to the base tramp:
1144         1. Ordinary 5-byte jump instruction.
1145         2. 2-byte jump to the extra slot in the entry point
1146         3. Trap instruction.
1147      */
1148
1149   // VG(7/29/02): Added sequence to pad the rest of the point with nops
1150   // This is vital if one has to debug the instrumented mutatee...
1151
1152   int wrote = 0;
1153
1154   /* Ordinary 5-byte jump */
1155   if (point->size() >= JUMP_REL32_SZ) {
1156     // replace instructions at point with jump to base tramp
1157     emitJump(baseAddr - (point->jumpAddr() + imageBaseAddr + JUMP_REL32_SZ), insn);
1158     wrote = JUMP_REL32_SZ;
1159   }
1160   /* Extra slot */
1161   else if (point->canUseExtraSlot(proc)) {
1162     pd_Function *f = point->func();
1163     const instPoint *the_entry = f->funcEntry(proc);
1164     
1165     int displacement = the_entry->jumpAddr() + 5 - point->jumpAddr();
1166     assert(displacement < 0);
1167     assert((displacement-2) > SCHAR_MIN);
1168     assert(point->size() >= 2);
1169 #ifdef INST_TRAP_DEBUG
1170     cerr << "Using extra slot in entry of " << f->prettyName()
1171          << " to avoid need for trap @" << (void*)point->address() << endl;
1172 #endif
1173     
1174     instPoint *nonConstEntry = const_cast<instPoint *>(the_entry);
1175     returnInstance *retInstance;
1176     
1177     trampTemplate *entryBase =
1178       findAndInstallBaseTramp(proc, nonConstEntry,
1179                               retInstance, false, false, deferred);
1180     assert(entryBase);
1181     if (retInstance) {
1182       retInstance->installReturnInstance(proc);
1183     }
1184     generateBranch(proc, the_entry->jumpAddr()+imageBaseAddr+5, baseAddr);
1185     *insn++ = 0xEB;
1186     *insn++ = (char)(displacement-2);
1187     wrote = 2;
1188   }
1189   else { /* Trap */
1190 #ifdef INST_TRAP_DEBUG
1191     cerr << "Warning: unable to insert jump in function " 
1192          << point->func()->prettyName() << " @" << (void*)point->address()
1193          << ". Using trap!" << endl;
1194 #endif
1195     if (!insertInTrampTable(proc, point->jumpAddr()+imageBaseAddr, baseAddr))
1196       return 0;
1197     *insn++ = 0xCC;
1198     wrote = 1;
1199   }
1200   
1201   // VG(8/4/2): For reasons yet to be determined, this breaks test1 (on x86)
1202   // So don't enable it unless you are working on test6/memory instrumentation
1203 #ifdef IA32_NOP_PADDING
1204    for(int rest = point->size() - wrote; rest > 0; --rest, ++insn)
1205      *insn = 0x90;
1206    return point->size();
1207 #else
1208   return wrote;
1209 #endif
1210 }
1211
1212 /****************************************************************************/
1213 /****************************************************************************/
1214 /****************************************************************************/
1215
1216 #if defined(i386_unknown_solaris2_5) || \
1217     defined(i386_unknown_linux2_0) || \
1218     defined(i386_unknown_nt4_0)
1219 int guard_code_before_pre_instr_size  = 19; /* size in bytes */
1220 int guard_code_after_pre_instr_size   = 10; /* size in bytes */
1221 int guard_code_before_post_instr_size = 19; /* size in bytes */
1222 int guard_code_after_post_instr_size  = 10; /* size in bytes */
1223 #else
1224 int guard_code_before_pre_instr_size  = 0; /* size in bytes */
1225 int guard_code_after_pre_instr_size   = 0; /* size in bytes */
1226 int guard_code_before_post_instr_size = 0; /* size in bytes */
1227 int guard_code_after_post_instr_size  = 0; /* size in bytes */
1228 #endif
1229
1230 /****************************************************************************/
1231 /****************************************************************************/
1232 /****************************************************************************/
1233
1234 unsigned int get_guard_code_size() /* total size in bytes of the four
1235                                       guard code fragments*/
1236 {
1237   return
1238     guard_code_before_pre_instr_size +
1239     guard_code_after_pre_instr_size +
1240     guard_code_before_post_instr_size +
1241     guard_code_after_post_instr_size;
1242 }
1243
1244 /****************************************************************************/
1245 /****************************************************************************/
1246 /****************************************************************************/
1247
1248 void emitJccR8( int condition_code,
1249                 char jump_offset,
1250                 unsigned char * & instruction )
1251 {
1252   *instruction++ = condition_code;
1253   *instruction++ = jump_offset;
1254 }
1255
1256 // VG(8/15/02): nicer jcc: condition is the tttn field.
1257 // Because we generate jumps twice, once with bogus 0
1258 // offset, and then with the right offset, the instruction
1259 // may be longer (and overwrite something else) the 2nd time.
1260 // So willRegen defaults to true and always generates jcc near
1261 // (the longer form)
1262
1263 // TODO: generate JEXCZ as well
1264 static inline void emitJcc(int condition, int offset, unsigned char*& instruction, 
1265                            bool willRegen=true)
1266 {
1267   unsigned char opcode;
1268
1269   assert(condition >= 0 && condition <= 0x0F);
1270
1271   if(!willRegen && (offset >= -128 && offset <= 127)) { // jcc rel8
1272     opcode = 0x70 | (unsigned char)condition;
1273     *instruction++ = opcode;
1274     *instruction++ = (unsigned char) (offset & 0xFF);
1275   }
1276   else { // jcc near rel32
1277     opcode = 0x80 | (unsigned char)condition;
1278     *instruction++ = 0x0F;
1279     *instruction++ = opcode;
1280     *((int*)instruction) = offset;
1281     instruction += sizeof(int);
1282   }
1283 }
1284
1285
1286 /****************************************************************************/
1287 /****************************************************************************/
1288 /****************************************************************************/
1289
1290 #if defined(i386_unknown_solaris2_5) || \
1291     defined(i386_unknown_linux2_0) || \
1292     defined(i386_unknown_nt4_0)
1293 void generate_guard_code( unsigned char * buffer,
1294                           const NonRecursiveTrampTemplate & base_template,
1295                           Address /* base_address */,
1296                           Address guard_flag_address )
1297 {
1298   unsigned char * instruction;
1299
1300   /* guard-on code before pre instr */
1301   /* Code generated:
1302    * --------------
1303    * cmpl   $0x0, (guard flag address)
1304    * je     <after guard-off code>
1305    * movl   $0x0, (guard flag address)
1306    */
1307   instruction = buffer + base_template.guardOnPre_beginOffset;
1308   /*            CMP_                       (memory address)__  0 */
1309   emitOpRMImm8( 0x83, 0x07, Null_Register, guard_flag_address, 0, instruction );
1310   emitJccR8( JE_R8, buffer + base_template.guardOffPre_endOffset - ( instruction + 2 ), instruction );
1311   emitMovImmToMem( guard_flag_address, 0, instruction );
1312
1313   /* guard-off code after pre instr */
1314   /* Code generated:
1315    * --------------
1316    * movl   $0x1, (guard flag address)
1317    */
1318   instruction = buffer + base_template.guardOffPre_beginOffset;
1319   emitMovImmToMem( guard_flag_address, 1, instruction );
1320
1321   /* guard-on code before post instr */
1322   instruction = buffer + base_template.guardOnPost_beginOffset;
1323   emitOpRMImm8( 0x83, 0x07, Null_Register, guard_flag_address, 0x00, instruction );
1324   emitJccR8( JE_R8, buffer + base_template.guardOffPost_endOffset - ( instruction + 2 ), instruction );
1325   emitMovImmToMem( guard_flag_address, 0, instruction );
1326
1327   /* guard-off code after post instr */
1328   instruction = buffer + base_template.guardOffPost_beginOffset;
1329   emitMovImmToMem( guard_flag_address, 1, instruction );
1330 }
1331 #else
1332 void generate_guard_code( unsigned char * /* buffer */,
1333                           const NonRecursiveTrampTemplate & /* base_template */,
1334                           Address /* base_address */,
1335                           Address /* guard_flag_address */ )
1336 {
1337 }
1338 #endif
1339
1340 void generateMTpreamble(char *, Address &, process *) {
1341         assert( 0 );    // We don't yet handle multiple threads.
1342         } /* end generateMTpreamble() */
1343
1344 /****************************************************************************/
1345 /****************************************************************************/
1346 /****************************************************************************/
1347
1348 /*
1349  * Install a base tramp, relocating the instructions at location
1350  * The pre and post jumps are filled with a 'jump 0'
1351  * Return a descriptor for the base tramp.
1352  *
1353  */
1354
1355 trampTemplate *installBaseTramp( const instPoint *location,
1356                                  process *proc,
1357                                  bool noCost,
1358                                  bool trampRecursiveDesired = true
1359                                  ) 
1360 {  
1361    bool aflag;
1362   
1363 /*
1364    The base tramp:
1365    addr   instruction             cost
1366    0:    <relocated instructions before point>
1367    a = size of relocated instructions before point
1368    a+0:   jmp a+30 <skip pre insn>  1
1369    a+5:   pushfd                    5
1370    a+6:   pushad                    9
1371    a+7:   push ebp                  1
1372    a+8:   mov esp, ebp              1
1373    a+10:  subl esp, 0x80            1
1374    a+16:  jmp <global pre inst>     1
1375    a+21:  jmp <local pre inst>      1
1376    a+26:  leave                     3
1377    a+27:  popad                    14
1378    a+28:  popfd                     5
1379    a+29:  add costAddr, cost        3
1380    a+39:  <relocated instructions at point>
1381
1382    b = a +30 + size of relocated instructions at point
1383    b+0:   jmp b+30 <skip post insn>
1384    b+5:   pushfd
1385    b+6:   pushad
1386    b+7:   push ebp
1387    b+8:   mov esp, ebp
1388    b+10:  subl esp, 0x80
1389    b+16:  jmp <global post inst>
1390    b+21:  jmp <local post inst>
1391    b+26:  leave
1392    b+27:  popad
1393    b+28:  popfd
1394    b+29:  <relocated instructions after point>
1395
1396    c:     jmp <return to user code>
1397
1398    tramp size = 2*23 + 10 + 5 + size of relocated instructions
1399    Make sure to update the size if the tramp is changed
1400
1401    cost of pre and post instrumentation is (1+1+1+5+9+1+1+15+5+3) = 42
1402    cost of rest of tramp is (1+3+1+1)
1403
1404    [mihai Wed Apr 12 00:22:03 CDT 2000]
1405      Additionally, if a guarded template is generated
1406      (i.e. trampRecursiveDesired = false), four more code fragments are inserted:
1407      - code to turn the guard on (19 bytes): between a+15 and a+16, and
1408                                              between b+15 and b+16
1409      - code to turn the guard off (10 bytes): between a+21 and a+26, and
1410                                               between b+21 and b+26
1411      A total of 58 bytes are added to the base tramp.
1412 */
1413
1414    //pd_Function *f = location->func();
1415
1416   unsigned u;
1417   trampTemplate *ret = 0;
1418   if( trampRecursiveDesired )
1419     {
1420       ret = new trampTemplate;
1421     }
1422   else
1423     {
1424       ret = new NonRecursiveTrampTemplate;
1425     }
1426   ret->trampTemp = 0;
1427
1428   unsigned jccTarget = 0; // used when the instruction at the point is a cond. jump
1429   unsigned auxJumpOffset = 0;
1430
1431   // compute the tramp size
1432   // if there are any changes to the tramp, the size must be updated.
1433 #if defined(SHM_SAMPLING) && defined(MT_THREAD)
1434   unsigned trampSize = 73+2*27 + 66;
1435 #else
1436   unsigned trampSize = 73;
1437 #endif
1438
1439   if (location->isConservative()) trampSize += 13*2;
1440
1441   if( ! trampRecursiveDesired ) {
1442       trampSize += get_guard_code_size();   // NOTE-131 with Relocation
1443   }
1444
1445   for (u = 0; u < location->insnsBefore(); u++) {
1446     trampSize += getRelocatedInstructionSz(location->insnBeforePt(u));
1447   }
1448
1449   if (location->insnAtPoint().type() & IS_JCC) {
1450     trampSize += location->insnAtPoint().size() + 2 * JUMP_SZ;
1451   } else {
1452     trampSize += getRelocatedInstructionSz(location->insnAtPoint());
1453   }
1454   
1455   for (u = 0; u < location->insnsAfter(); u++) {
1456     trampSize += getRelocatedInstructionSz(location->insnAfterPt(u));
1457   }
1458
1459
1460   Address imageBaseAddr;
1461   if (!proc->getBaseAddress(location->owner(), imageBaseAddr)) {
1462     abort();
1463   }
1464
1465   Address costAddr = 0; // for now...
1466   if (!noCost) {
1467 #ifdef SHM_SAMPLING
1468      costAddr = (Address)proc->getObsCostLowAddrInApplicSpace();
1469      assert(costAddr);
1470 #else
1471      // get address of DYNINSTobsCostLow to update observed cost
1472      bool err = false;
1473      costAddr = proc->findInternalAddress("DYNINSTobsCostLow",
1474                                           true, err);
1475      assert(costAddr && !err);
1476 #endif
1477   }
1478
1479   ret->size = trampSize;
1480   Address baseAddr = proc->inferiorMalloc(trampSize, textHeap);
1481   // cout << "installBaseTramp(): trampoline base address = 0x"
1482   //      << setw( 8 ) << setfill( '0' ) << hex << baseAddr << dec << endl;
1483   ret->baseAddr = baseAddr;
1484
1485   unsigned char *code = new unsigned char[2*trampSize];
1486   unsigned char *insn = code;
1487   Address currAddr = baseAddr;
1488
1489   // MT FIXME
1490
1491   // get the current instruction that is being executed. If the PC is at a
1492   // instruction that is being relocated, we must change the PC.
1493
1494   Frame frame = proc->getDefaultLWP()->getActiveFrame();
1495   Address currentPC = frame.getPC();
1496
1497   // emulate the instructions before the point
1498   Address origAddr = location->jumpAddr() + imageBaseAddr;
1499
1500   for (u = location->insnsBefore(); u > 0; ) {
1501     --u;
1502     if (currentPC == origAddr) {
1503
1504       //fprintf(stderr, "changed PC: 0x%lx to 0x%lx\n", currentPC, currAddr);
1505       proc->getDefaultLWP()->changePC(currAddr, NULL);
1506     }
1507
1508     unsigned newSize = relocateInstruction(location->insnBeforePt(u), origAddr, currAddr, insn);
1509     aflag=(newSize == getRelocatedInstructionSz(location->insnBeforePt(u)));
1510     assert(aflag);
1511     currAddr += newSize;
1512     origAddr += location->insnBeforePt(u).size();
1513   }
1514
1515
1516   /***
1517     If the instruction at the point is a conditional jump, we relocate it to
1518     the top of the base tramp, and change the code so that the tramp is executed
1519     only if the branch is taken.
1520
1521     e.g.
1522      L1:  jne target
1523      L2:  ...
1524
1525     becomes
1526
1527           jne T1
1528           jmp T2
1529           jne
1530      T1:  ...
1531
1532      T2:  relocated instructions after point
1533
1534      then later at the base tramp, at the point where we relocate the instruction
1535      at the point, we insert a jump to target
1536   ***/
1537   if (location->insnAtPoint().type() & IS_JCC) {
1538
1539      currAddr = baseAddr + (insn - code);
1540      assert(origAddr == location->address() + imageBaseAddr);
1541      origAddr = location->address() + imageBaseAddr;
1542      if (currentPC == origAddr &&
1543          currentPC != (location->jumpAddr() + imageBaseAddr)) {
1544        //fprintf(stderr, "changed PC: 0x%lx to 0x%lx\n", currentPC, currAddr);
1545        proc->getDefaultLWP()->changePC(currAddr, NULL);
1546      }
1547
1548      jccTarget = changeConditionalJump(location->insnAtPoint(), origAddr, currAddr,
1549                                        currAddr+location->insnAtPoint().size()+5, insn);
1550      currAddr += location->insnAtPoint().size();
1551      auxJumpOffset = insn-code;
1552      emitJump(0, insn);
1553      origAddr += location->insnAtPoint().size();
1554   }
1555
1556   if (location->isConservative() && !noCost)
1557     emitSimpleInsn(PUSHFD, insn);    // pushfd
1558
1559   // pre branches
1560   // skip pre instrumentation
1561   ret->skipPreInsOffset = insn-code;
1562   emitJump(0, insn);
1563
1564   // save registers and create a new stack frame for the tramp
1565   ret->savePreInsOffset = insn-code;
1566   if (!location->isConservative() || noCost)
1567     emitSimpleInsn(PUSHFD, insn);    // pushfd
1568   emitSimpleInsn(PUSHAD, insn);    // pushad
1569   emitSimpleInsn(PUSH_EBP, insn);  // push ebp
1570   emitMovRegToReg(EBP, ESP, insn); // mov ebp, esp  (2-byte instruction)
1571   if (location->isConservative()) {
1572     // allocate space for temporaries (virtual registers) and floating point state
1573     emitOpRegImm(5, ESP, 128 + FSAVE_STATE_SIZE, insn); // sub esp, 128
1574     // save floating point state
1575     emitOpRegRM(FSAVE, FSAVE_OP, EBP, -128 - FSAVE_STATE_SIZE, insn);
1576   } else {
1577     // allocate space for temporaries (virtual registers)
1578     emitOpRegImm(5, ESP, 128, insn); // sub esp, 128
1579   }
1580
1581 #if defined(SHM_SAMPLING) && defined(MT_THREAD)
1582   // generate preamble for MT version
1583   Address base=0;
1584   generateMTpreamble((char *)insn, base, proc);
1585   insn += base;
1586 #endif
1587
1588   if( ! trampRecursiveDesired )
1589     {
1590       NonRecursiveTrampTemplate * temp_ret = ( NonRecursiveTrampTemplate * )ret;
1591       temp_ret->guardOnPre_beginOffset = insn - code;
1592       for( int i = 0; i < guard_code_before_pre_instr_size; i++ )
1593         emitSimpleInsn( 0x90, insn );
1594       temp_ret->guardOnPre_endOffset = insn - code;
1595     }
1596
1597   // global pre branch
1598   ret->globalPreOffset = insn-code;
1599   emitJump(0, insn);
1600
1601   // local pre branch
1602   ret->localPreOffset = insn-code;
1603   emitJump(0, insn);
1604
1605   ret->localPreReturnOffset = insn-code;
1606
1607   if( ! trampRecursiveDesired )
1608     {
1609       NonRecursiveTrampTemplate * temp_ret = ( NonRecursiveTrampTemplate * )ret;
1610       temp_ret->guardOffPre_beginOffset = insn - code;
1611       for( int i = 0; i < guard_code_after_pre_instr_size; i++ )
1612         emitSimpleInsn( 0x90, insn );
1613       temp_ret->guardOffPre_endOffset = insn - code;
1614     }
1615
1616   // restore registers
1617   if (location->isConservative())
1618     emitOpRegRM(FRSTOR, FRSTOR_OP, EBP, -128 - FSAVE_STATE_SIZE, insn);
1619   emitSimpleInsn(LEAVE, insn);     // leave
1620   emitSimpleInsn(POPAD, insn);     // popad
1621   if (!location->isConservative() || noCost)
1622     emitSimpleInsn(POPFD, insn);     // popfd
1623   ret->restorePreInsOffset = insn-code;
1624
1625   // update cost
1626   // update cost -- a 10-byte instruction
1627   ret->updateCostOffset = insn-code;
1628   currAddr = baseAddr + (insn-code);
1629   ret->costAddr = currAddr;
1630   if (!noCost) {
1631      emitAddMemImm32(costAddr, 88, insn);  // add (costAddr), cost
1632      if (location->isConservative())
1633        emitSimpleInsn(POPFD, insn);     // popfd
1634   }
1635   else {
1636      // minor hack: we still need to fill up the rest of the 10 bytes, since
1637      // assumptions are made about the positioning of instructions that follow.
1638      // (This could in theory be fixed)
1639      // So, 10 NOP instructions (each 1 byte)
1640      for (unsigned foo=0; foo < 10; foo++)
1641         emitSimpleInsn(0x90, insn); // NOP
1642   }
1643    
1644   if (!(location->insnAtPoint().type() & IS_JCC)) {
1645     // emulate the instruction at the point 
1646     ret->emulateInsOffset = insn-code;
1647     currAddr = baseAddr + (insn - code);
1648     assert(origAddr == location->address() + imageBaseAddr);
1649     origAddr = location->address() + imageBaseAddr;
1650     if (currentPC == origAddr &&
1651         currentPC != (location->jumpAddr() + imageBaseAddr)) {
1652       //fprintf(stderr, "changed PC: 0x%lx to 0x%lx\n", currentPC, currAddr);
1653       proc->getDefaultLWP()->changePC(currAddr, NULL);
1654     }
1655
1656     unsigned newSize = relocateInstruction(location->insnAtPoint(), origAddr, currAddr, insn);
1657     aflag=(newSize == getRelocatedInstructionSz(location->insnAtPoint()));
1658     assert(aflag);
1659     currAddr += newSize;
1660     origAddr += location->insnAtPoint().size();
1661   } else {
1662     // instruction at point is a conditional jump. 
1663     // The instruction was relocated to the beggining of the tramp (see comments above)
1664     // We must generate a jump to the original target here
1665     assert(jccTarget > 0);
1666     currAddr = baseAddr + (insn - code);
1667     emitJump(jccTarget-(currAddr+JUMP_SZ), insn);
1668     currAddr += JUMP_SZ;
1669   }
1670
1671   // post branches
1672   // skip post instrumentation
1673   ret->skipPostInsOffset = insn-code;
1674   emitJump(0, insn);
1675
1676
1677   // save registers and create a new stack frame for the tramp
1678   ret->savePostInsOffset = insn-code;
1679   emitSimpleInsn(PUSHFD, insn);    // pushfd
1680   emitSimpleInsn(PUSHAD, insn);    // pushad
1681   emitSimpleInsn(PUSH_EBP, insn);  // push ebp
1682   emitMovRegToReg(EBP, ESP, insn); // mov ebp, esp
1683   // allocate space for temporaries (virtual registers)
1684   if (location->isConservative()) {
1685     // allocate space for temporaries (virtual registers) and floating point state
1686     emitOpRegImm(5, ESP, 128 + FSAVE_STATE_SIZE, insn); // sub esp, 128
1687     // save floating point state
1688     emitOpRegRM(FSAVE, FSAVE_OP, EBP, -128 - FSAVE_STATE_SIZE, insn);
1689   } else {
1690     // allocate space for temporaries (virtual registers)
1691     emitOpRegImm(5, ESP, 128, insn); // sub esp, 128
1692   }
1693
1694 #if defined(SHM_SAMPLING) && defined(MT_THREAD)
1695   // generate preamble for MT version
1696   base=0;
1697   generateMTpreamble((char *)insn, base, proc);
1698   insn += base;
1699 #endif
1700
1701   if( ! trampRecursiveDesired )
1702     {
1703       NonRecursiveTrampTemplate * temp_ret = ( NonRecursiveTrampTemplate * )ret;
1704       temp_ret->guardOnPost_beginOffset = insn - code;
1705       for( int i = 0; i < guard_code_before_post_instr_size; i++ )
1706         emitSimpleInsn( 0x90, insn );
1707       temp_ret->guardOnPost_endOffset = insn - code;
1708     }
1709
1710   // global post branch
1711   ret->globalPostOffset = insn-code; 
1712   emitJump(0, insn);
1713
1714   // local post branch
1715   ret->localPostOffset = insn-code;
1716   emitJump(0, insn);
1717
1718   ret->localPostReturnOffset = insn-code;
1719
1720   if( ! trampRecursiveDesired )
1721     {
1722       NonRecursiveTrampTemplate * temp_ret = ( NonRecursiveTrampTemplate * )ret;
1723       temp_ret->guardOffPost_beginOffset = insn - code;
1724       for( int i = 0; i < guard_code_after_post_instr_size; i++ )
1725         emitSimpleInsn( 0x90, insn );
1726       temp_ret->guardOffPost_endOffset = insn - code;
1727     }
1728
1729   // restore registers
1730   if (location->isConservative())
1731     emitOpRegRM(FRSTOR, FRSTOR_OP, EBP, -128 - FSAVE_STATE_SIZE, insn);
1732   emitSimpleInsn(LEAVE, insn);     // leave
1733   emitSimpleInsn(POPAD, insn);     // popad
1734   emitSimpleInsn(POPFD, insn);     // popfd
1735   ret->restorePostInsOffset = insn-code;
1736   
1737   // emulate the instructions after the point
1738   ret->returnInsOffset = insn-code;
1739   currAddr = baseAddr + (insn - code);
1740   assert(origAddr == location->address() + imageBaseAddr + location->insnAtPoint().size());
1741   origAddr = location->address() + imageBaseAddr + location->insnAtPoint().size();
1742   for (u = 0; u < location->insnsAfter(); u++) {
1743     if (currentPC == origAddr) {
1744       //fprintf(stderr, "changed PC: 0x%lx to 0x%lx\n", currentPC, currAddr);
1745       proc->getDefaultLWP()->changePC(currAddr, NULL);
1746     }
1747     unsigned newSize = relocateInstruction(location->insnAfterPt(u), origAddr, currAddr, insn);
1748     aflag=(newSize == getRelocatedInstructionSz(location->insnAfterPt(u)));
1749     assert(aflag);
1750     currAddr += newSize;
1751     origAddr += location->insnAfterPt(u).size();
1752   }
1753
1754   // return to user code
1755   currAddr = baseAddr + (insn - code);
1756   emitJump(location->returnAddr()+imageBaseAddr - (currAddr+JUMP_SZ), insn);
1757 #ifdef INST_TRAP_DEBUG
1758   cerr << "installBaseTramp jump back to " <<
1759           (void*)( location->returnAddr() + imageBaseAddr ) << endl;
1760 #endif
1761
1762   assert((unsigned)(insn-code) == trampSize);
1763
1764   // update the jumps to skip pre and post instrumentation
1765   unsigned char *ip = code + ret->skipPreInsOffset;
1766   emitJump(ret->updateCostOffset - (ret->skipPreInsOffset+JUMP_SZ), ip);
1767   ip = code + ret->skipPostInsOffset;
1768   emitJump(ret->returnInsOffset - (ret->skipPostInsOffset+JUMP_SZ), ip);
1769
1770   if (auxJumpOffset > 0) {
1771     ip = code + auxJumpOffset;
1772     emitJump(ret->returnInsOffset - (auxJumpOffset+JUMP_SZ), ip);
1773   }
1774
1775   if( ! trampRecursiveDesired )
1776     {
1777       /* prepare guard flag memory, if needed */
1778       Address guardFlagAddress = proc->trampGuardAddr();
1779
1780       NonRecursiveTrampTemplate * temp_ret = ( NonRecursiveTrampTemplate * )ret;
1781       generate_guard_code( code, * temp_ret, baseAddr, guardFlagAddress );
1782     }
1783   
1784   // put the tramp in the application space
1785   proc->writeDataSpace((caddr_t)baseAddr, insn-code, (caddr_t) code);
1786
1787   delete [] code;
1788
1789   ret->cost = 6;
1790   //
1791   // The cost for generateMTpreamble is 25 for pre and post instrumentation:
1792   // movl   $0x80570ec,%eax                1
1793   // call   *%ea                           5
1794   // movl   %eax,0xfffffffc(%ebp)          1
1795   // shll   $0x2,0xfffffffc(%ebp)         12
1796   // addl   $0x84ac670,0xfffffffc(%ebp)    4
1797   // movl   0xfffffffc(%ebp),%eax          1
1798   // movl   %eax,0xffffff80(%ebp)          1
1799   //
1800   ret->prevBaseCost = 42+25;
1801   ret->postBaseCost = 42+25;
1802   ret->prevInstru = false;
1803   ret->postInstru = false;
1804   return ret;
1805 }
1806
1807
1808 // This function is used to clear a jump from base to minitramps
1809 // For the x86 platform, we generate a jump to the next instruction
1810 void generateNoOp(process *proc, Address addr) 
1811 {
1812   static unsigned char jump0[5] = { 0xE9, 0, 0, 0, 0 };
1813   proc->writeDataSpace((caddr_t) addr, 5, (caddr_t)jump0);
1814 }
1815
1816
1817 trampTemplate* findAndInstallBaseTramp(process *proc, 
1818                                        instPoint *&location, 
1819                                        returnInstance *&retInstance,
1820                                        bool trampRecursiveDesired,
1821                                        bool noCost,
1822                                        bool &deferred)
1823 {
1824     trampTemplate *ret;
1825     retInstance = NULL;
1826
1827     pd_Function *f = location->func();
1828
1829     // location may not have been updated since relocation of function
1830     if (f->needsRelocation() && f->isInstalled(proc)) {
1831       f->modifyInstPoint(const_cast<const instPoint *&>(location), proc);
1832     }
1833
1834     if (!proc->baseMap.defines(location)) {
1835
1836         // if function needs relocation  
1837         if (f->needsRelocation()) {
1838         
1839           // if function has not already been relocated
1840           if (!f->isInstalled(proc)) {
1841             bool relocated = f->relocateFunction(proc, location, deferred);
1842      
1843             // Silence warnings
1844             assert(relocated || true);
1845
1846 #ifndef BPATCH_LIBRARY
1847             if (!relocated) return NULL;
1848 #endif
1849           }
1850         }
1851
1852         ret = installBaseTramp(location, proc, noCost, trampRecursiveDesired);
1853         proc->baseMap[location] = ret;
1854
1855         // generate branch from instrumentation point to base tramp
1856         Address imageBaseAddr;
1857         if (!proc->getBaseAddress(location->owner(), imageBaseAddr))
1858           abort();
1859         unsigned char *insn = new unsigned char[JUMP_REL32_SZ];
1860         unsigned size = generateBranchToTramp(proc, location, ret->baseAddr, 
1861                                               imageBaseAddr, insn, deferred);
1862         if (size == 0)
1863           return NULL;
1864         retInstance = new returnInstance(location->insns(), 
1865                                          new instruction(insn, 0, size), size,
1866                                          location->jumpAddr() + imageBaseAddr, 
1867                                          size);
1868
1869     } else {
1870         ret = proc->baseMap[location];
1871     }
1872     return(ret);
1873 }
1874
1875
1876 /*
1877  * Install a single mini-tramp.
1878  *
1879  */
1880 void installTramp(instInstance *inst, process *proc, char *code, int codeSize,
1881                   instPoint * /*location*/, callWhen when)
1882 {
1883     totalMiniTramps++;
1884     //insnGenerated += codeSize/sizeof(int);
1885     proc->writeDataSpace((caddr_t)inst->trampBase, codeSize, code);
1886     Address atAddr;
1887     if (when == callPreInsn) {
1888         if (inst->baseInstance->prevInstru == false) {
1889             atAddr = inst->baseInstance->baseAddr+inst->baseInstance->skipPreInsOffset;
1890             inst->baseInstance->cost += inst->baseInstance->prevBaseCost;
1891             inst->baseInstance->prevInstru = true;
1892             generateNoOp(proc, atAddr);
1893         }
1894     }
1895     else {
1896         if (inst->baseInstance->postInstru == false) {
1897             atAddr = inst->baseInstance->baseAddr+inst->baseInstance->skipPostInsOffset; 
1898             inst->baseInstance->cost += inst->baseInstance->postBaseCost;
1899             inst->baseInstance->postInstru = true;
1900             generateNoOp(proc, atAddr);
1901         }
1902     }
1903 }
1904
1905
1906 /**************************************************************
1907  *
1908  *  code generator for x86
1909  *
1910  **************************************************************/
1911
1912
1913
1914
1915 #define MAX_BRANCH      (0x1<<31)
1916
1917 Address getMaxBranch() {
1918   return (Address)MAX_BRANCH;
1919 }
1920
1921
1922 bool doNotOverflow(int)
1923 {
1924   //
1925   // this should be changed by the correct code. If there isn't any case to
1926   // be checked here, then the function should return TRUE. If there isn't
1927   // any immediate code to be generated, then it should return FALSE - naim
1928   //
1929   // any int value can be an immediate on the pentium
1930   return(true);
1931 }
1932
1933
1934
1935 /* build the MOD/RM byte of an instruction */
1936 static inline unsigned char makeModRMbyte(unsigned Mod, unsigned Reg, unsigned RM)
1937 {
1938   return ((Mod & 0x3) << 6) + ((Reg & 0x7) << 3) + (RM & 0x7);
1939 }
1940
1941 // VG(7/30/02): Build the SIB byte of an instruction */
1942 static inline unsigned char makeSIBbyte(unsigned Scale, unsigned Index, unsigned Base)
1943 {
1944   return ((Scale & 0x3) << 6) + ((Index & 0x7) << 3) + (Base & 0x7);
1945 }
1946
1947 /* 
1948    Emit the ModRM byte and displacement for addressing modes.
1949    base is a register (EAX, ECX, EDX, EBX, EBP, ESI, EDI)
1950    disp is a displacement
1951    reg_opcode is either a register or an opcode
1952 */
1953 static inline void emitAddressingMode(Register base, RegValue disp, int reg_opcode, 
1954                                       unsigned char *&insn)
1955 {
1956   assert(base != ESP);
1957   if (base == Null_Register) {
1958     *insn++ = makeModRMbyte(0, reg_opcode, 5);
1959     *((int *)insn) = disp;
1960     insn += sizeof(int);
1961   } else if (disp == 0 && base != EBP) {
1962     *insn++ = makeModRMbyte(0, reg_opcode, base);
1963   } else if (disp >= -128 && disp <= 127) {
1964     *insn++ = makeModRMbyte(1, reg_opcode, base);
1965     *((char *)insn++) = (char) disp;
1966   } else {
1967     *insn++ = makeModRMbyte(2, reg_opcode, base);
1968     *((int *)insn) = disp;
1969     insn += sizeof(int);
1970   }
1971 }
1972
1973 // VG(7/30/02): emit a fully fledged addressing mode: base+index<<scale+disp
1974 static inline void emitAddressingMode(Register base, Register index, unsigned int scale,
1975                                       RegValue disp, int reg_opcode, unsigned char *&insn)
1976 {
1977   bool needSIB = (base == ESP) || (index != Null_Register);
1978
1979   if(!needSIB) {
1980     emitAddressingMode(base, disp, reg_opcode, insn);
1981     return;
1982   }
1983
1984   assert(index != ESP);
1985
1986   if(index == Null_Register) {
1987     assert(base == ESP); // not necessary, but sane
1988     index = 4;           // (==ESP) which actually means no index in SIB
1989   }
1990
1991   if(base == Null_Register) { // we have to emit [index<<scale+disp32]
1992     *insn++ = makeModRMbyte(0, reg_opcode, 4);
1993     *insn++ = makeSIBbyte(scale, index, 5);
1994     *((int *)insn) = disp;
1995     insn += sizeof(int);
1996   }
1997   else if(disp == 0 && base != EBP) { // EBP must have 0 disp8; emit [base+index<<scale]
1998     *insn++ = makeModRMbyte(0, reg_opcode, 4);
1999     *insn++ = makeSIBbyte(scale, index, base);
2000   }
2001   else if (disp >= -128 && disp <= 127) { // emit [base+index<<scale+disp8]
2002     *insn++ = makeModRMbyte(1, reg_opcode, 4);
2003     *insn++ = makeSIBbyte(scale, index, base);
2004     *((char *)insn++) = (char) disp;
2005   }
2006   else { // emit [base+index<<scale+disp32]
2007     *insn++ = makeModRMbyte(2, reg_opcode, 4);
2008     *insn++ = makeSIBbyte(scale, index, base);
2009     *((int *)insn) = disp;
2010     insn += sizeof(int);
2011   }
2012 }
2013
2014
2015 /* emit a simple one-byte instruction */
2016 static inline void emitSimpleInsn(unsigned op, unsigned char *&insn) {
2017   *insn++ = op;
2018 }
2019
2020 // emit a simple register to register instruction: OP dest, src
2021 // opcode is one or two byte
2022 static inline void emitOpRegReg(unsigned opcode, Register dest, Register src,
2023                   unsigned char *&insn) {
2024   if (opcode <= 0xFF)
2025     *insn++ = opcode;
2026   else {
2027     *insn++ = opcode >> 8;
2028     *insn++ = opcode & 0xFF;
2029   }
2030   // ModRM byte define the operands: Mod = 3, Reg = dest, RM = src
2031   *insn++ = makeModRMbyte(3, dest, src);
2032 }
2033
2034 // emit OP reg, r/m
2035 static inline void emitOpRegRM(unsigned opcode, Register dest, Register base, int disp,
2036                  unsigned char *&insn) {
2037   if (opcode <= 0xff) {
2038     *insn++ = opcode;
2039   } else {
2040     *insn++ = opcode >> 8;
2041     *insn++ = opcode & 0xff;
2042   }
2043   emitAddressingMode(base, disp, dest, insn);
2044 }
2045
2046 // emit OP r/m, reg
2047 static inline void emitOpRMReg(unsigned opcode, Register base, int disp, Register src,
2048                  unsigned char *&insn) {
2049   *insn++ = opcode;
2050   emitAddressingMode(base, disp, src, insn);
2051 }
2052
2053 // emit OP reg, imm32
2054 static inline void emitOpRegImm(int opcode, Register dest, int imm, unsigned char *&insn) {
2055   *insn++ = 0x81;
2056   *insn++ = makeModRMbyte(3, opcode, dest);
2057   *((int *)insn) = imm;
2058   insn+= sizeof(int);
2059 }
2060
2061 /*
2062 // emit OP r/m, imm32
2063 void emitOpRMImm(unsigned opcode, Register base, int disp, int imm,
2064                  unsigned char *&insn) {
2065   *insn++ = 0x81;
2066   emitAddressingMode(base, disp, opcode, insn);
2067   *((int *)insn) = imm;
2068   insn += sizeof(int);
2069 }
2070 */
2071
2072 // emit OP r/m, imm32
2073 static inline void emitOpRMImm(unsigned opcode1, unsigned opcode2,
2074                                Register base, int disp, int imm, unsigned char *&insn) {
2075   *insn++ = opcode1;
2076   emitAddressingMode(base, disp, opcode2, insn);
2077   *((int *)insn) = imm;
2078   insn += sizeof(int);
2079 }
2080
2081 // emit OP r/m, imm8
2082 static inline void emitOpRMImm8(unsigned opcode1, unsigned opcode2,
2083                                 Register base, int disp, char imm, unsigned char *&insn) {
2084   *insn++ = opcode1;
2085   emitAddressingMode(base, disp, opcode2, insn);
2086   *insn++ = imm;
2087 }
2088
2089 // emit OP reg, r/m, imm32
2090 static inline void emitOpRegRMImm(unsigned opcode, Register dest,
2091                                   Register base, int disp, int imm, unsigned char *&insn) {
2092   *insn++ = opcode;
2093   emitAddressingMode(base, disp, dest, insn);
2094   *((int *)insn) = imm;
2095   insn += sizeof(int);
2096 }
2097
2098 // emit MOV reg, reg
2099 static inline void emitMovRegToReg(Register dest, Register src, unsigned char *&insn) {
2100   *insn++ = 0x8B;
2101   *insn++ = makeModRMbyte(3, dest, src);
2102 }
2103
2104 // emit MOV reg, r/m
2105 static inline void emitMovRMToReg(Register dest, Register base, int disp, unsigned char *&insn) {
2106   *insn++ = 0x8B;
2107   emitAddressingMode(base, disp, dest, insn);
2108 }
2109
2110 // emit MOV r/m, reg
2111 static inline void emitMovRegToRM(Register base, int disp, Register src, unsigned char *&insn) {
2112   *insn++ = 0x89;
2113   emitAddressingMode(base, disp, src, insn);
2114 }
2115
2116 // emit MOV m, reg
2117 static inline void emitMovRegToM(int disp, Register src, unsigned char *&insn) {
2118   *insn++ = 0x89;
2119   emitAddressingMode(Null_Register, disp, src, insn);
2120 }
2121
2122 // emit MOV reg, m
2123 static inline void emitMovMToReg(Register dest, int disp, unsigned char *&insn) {
2124   *insn++ = 0x8B;
2125   emitAddressingMode(Null_Register, disp, dest, insn);
2126 }
2127
2128 // emit MOV reg, imm32
2129 static inline void emitMovImmToReg(Register dest, int imm, unsigned char *&insn) {
2130   *insn++ = 0xB8 + dest;
2131   *((int *)insn) = imm;
2132   insn += sizeof(int);
2133 }
2134
2135 // emit MOV r/m32, imm32
2136 static inline void emitMovImmToRM(Register base, int disp, int imm, unsigned char *&insn) {
2137   *insn++ = 0xC7;
2138   emitAddressingMode(base, disp, 0, insn);
2139   *((int*)insn) = imm;
2140   insn += sizeof(int);
2141 }
2142
2143 // emit MOV mem32, imm32
2144 static inline void emitMovImmToMem(Address maddr, int imm, unsigned char *&insn) {
2145   *insn++ = 0xC7;
2146   // emit the ModRM byte: we use a 32-bit displacement for the address,
2147   // the ModRM value is 0x05
2148   *insn++ = 0x05;
2149   *((unsigned *)insn) = maddr;
2150   insn += sizeof(unsigned);
2151   *((int*)insn) = imm;
2152   insn += sizeof(int);
2153 }
2154
2155
2156 // emit Add dword ptr DS:[addr], imm
2157 static inline void emitAddMemImm32(Address addr, int imm, unsigned char *&insn) {
2158   *insn++ = 0x81;
2159   *insn++ = 0x05;
2160   *((unsigned *)insn) = addr;
2161   insn += sizeof(unsigned);
2162   *((int *)insn) = imm;
2163   insn += sizeof(int);
2164 }
2165
2166 // emit Add reg, imm32
2167 static inline void emitAddRegImm32(Register reg, int imm, unsigned char *&insn) {
2168   *insn++ = 0x81;
2169   *insn++ = makeModRMbyte(3, 0, reg);
2170   *((int *)insn) = imm;
2171   insn += sizeof(int);
2172 }
2173
2174 // emit Sub reg, reg
2175 static inline void emitSubRegReg(Register dest, Register src, unsigned char *&insn)
2176 {
2177   *insn++ = 0x2B;
2178   *insn++ = makeModRMbyte(3, dest, src);
2179 }
2180
2181 // emit JUMP rel32
2182 static inline void emitJump(unsigned disp32, unsigned char *&insn) {
2183   if ((signed)disp32 >= 0)
2184     assert (disp32 < unsigned(1<<31));
2185   else
2186     assert ((unsigned)(-(signed)disp32) < unsigned(1<<31));
2187   *insn++ = 0xE9;
2188   *((int *)insn) = disp32;
2189   insn += sizeof(int);
2190
2191
2192 // emit CALL rel32
2193 void emitCallRel32(unsigned disp32, unsigned char *&insn) {
2194   *insn++ = 0xE8;
2195   *((int *)insn) = disp32;
2196   insn += sizeof(int);
2197 }
2198
2199 // set dest=1 if src1 op src2, otherwise dest = 0
2200 void emitRelOp(unsigned op, Register dest, Register src1, Register src2,
2201                unsigned char *&insn) {
2202   //fprintf(stderr,"Relop dest = %d, src1 = %d, src2 = %d\n", dest, src1, src2);
2203   emitOpRegReg(0x29, ECX, ECX, insn);           // clear ECX
2204   emitMovRMToReg(EAX, EBP, -(src1*4), insn);    // mov eax, -(src1*4)[ebp]
2205   emitOpRegRM(0x3B, EAX, EBP, -(src2*4), insn); // cmp eax, -(src2*4)[ebp]
2206   unsigned char opcode;
2207   switch (op) {
2208     case eqOp: opcode = JNE_R8; break;
2209     case neOp: opcode = JE_R8; break;
2210     case lessOp: opcode = JGE_R8; break;
2211     case leOp: opcode = JG_R8; break;
2212     case greaterOp: opcode = JLE_R8; break;
2213     case geOp: opcode = JL_R8; break;
2214     default: assert(0);
2215   }
2216   *insn++ = opcode; *insn++ = 1;                // jcc 1
2217   emitSimpleInsn(0x40+ECX, insn);               // inc ECX
2218   emitMovRegToRM(EBP, -(dest*4), ECX, insn);    // mov -(dest*4)[ebp], ecx
2219
2220 }
2221
2222 // set dest=1 if src1 op src2imm, otherwise dest = 0
2223 void emitRelOpImm(unsigned op, Register dest, Register src1, int src2imm,
2224                   unsigned char *&insn) {
2225   //fprintf(stderr,"Relop dest = %d, src1 = %d, src2 = %d\n", dest, src1, src2);
2226   emitOpRegReg(0x29, ECX, ECX, insn);           // clear ECX
2227   emitMovRMToReg(EAX, EBP, -(src1*4), insn);    // mov eax, -(src1*4)[ebp]
2228   emitOpRegImm(0x3D, EAX, src2imm, insn);       // cmp eax, src2
2229   unsigned char opcode;
2230   switch (op) {
2231     case eqOp: opcode = JNE_R8; break;
2232     case neOp: opcode = JE_R8; break;
2233     case lessOp: opcode = JGE_R8; break;
2234     case leOp: opcode = JG_R8; break;
2235     case greaterOp: opcode = JLE_R8; break;
2236     case geOp: opcode = JL_R8; break;
2237     default: assert(0);
2238   }
2239   *insn++ = opcode; *insn++ = 1;                // jcc 1
2240   emitSimpleInsn(0x40+ECX, insn);               // inc ECX
2241   emitMovRegToRM(EBP, -(dest*4), ECX, insn);    // mov -(dest*4)[ebp], ecx
2242
2243 }
2244
2245 static inline void emitEnter(short imm16, unsigned char *&insn) {
2246   *insn++ = 0xC8;
2247   *((short*)insn) = imm16;
2248   insn += sizeof(short);
2249   *insn++ = 0;
2250 }
2251
2252
2253
2254 Register emitFuncCall(opCode op, 
2255                       registerSpace *rs,
2256                       char *ibuf, Address &base,
2257                       const pdvector<AstNode *> &operands, 
2258                       const string &callee, process *proc,
2259                       bool noCost, const function_base *calleefunc,
2260                       const pdvector<AstNode *> &ifForks,
2261                       const instPoint *location)
2262 {
2263   assert(op == callOp);
2264   Address addr;
2265   bool err;
2266   pdvector <Register> srcs;
2267
2268   if (calleefunc)
2269        addr = calleefunc->getEffectiveAddress(proc);
2270   else {
2271        addr = proc->findInternalAddress(callee, false, err);
2272        if (err) {
2273             function_base *func = proc->findOneFunction(callee);
2274             if (!func) {
2275                  ostrstream os(errorLine, 1024, ios::out);
2276                  os << "Internal error: unable to find addr of " << callee << endl;
2277                  logLine(errorLine);
2278                  showErrorCallback(80, (const char *) errorLine);
2279                  P_abort();
2280             }
2281             addr = func->getEffectiveAddress(proc);
2282        }
2283   }
2284   for (unsigned u = 0; u < operands.size(); u++)
2285       srcs.push_back((Register)operands[u]->generateCode_phase2(proc, rs, ibuf,
2286                                                                 base, noCost, 
2287                                                                 ifForks, location));
2288
2289   unsigned char *insn = (unsigned char *) ((void*)&ibuf[base]);
2290   unsigned char *first = insn;
2291
2292   // push arguments in reverse order, last argument first
2293   // must use int instead of unsigned to avoid nasty underflow problem:
2294   for (int i=srcs.size() - 1 ; i >= 0; i--) {
2295      emitOpRMReg(PUSH_RM_OPC1, EBP, -(srcs[i]*4), PUSH_RM_OPC2, insn);
2296      rs->freeRegister(srcs[i]);
2297   }
2298
2299   // make the call
2300   // we are using an indirect call here because we don't know the
2301   // address of this instruction, so we can't use a relative call.
2302   // TODO: change this to use a direct call
2303   emitMovImmToReg(EAX, addr, insn);       // mov eax, addr
2304   emitOpRegReg(CALL_RM_OPC1, CALL_RM_OPC2, EAX, insn);   // call *(eax)
2305
2306   // reset the stack pointer
2307   if (srcs.size() > 0)
2308      emitOpRegImm(0, ESP, srcs.size()*4, insn); // add esp, srcs.size()*4
2309
2310   // allocate a (virtual) register to store the return value
2311   Register ret = rs->allocateRegister((char *)insn, base, noCost);
2312   emitMovRegToRM(EBP, -(ret*4), EAX, insn);
2313
2314   base += insn - first;
2315   return ret;
2316 }
2317
2318
2319
2320 /*
2321  * emit code for op(src1,src2, dest)
2322  * ibuf is an instruction buffer where instructions are generated
2323  * base is the next free position on ibuf where code is to be generated
2324  */
2325
2326 Address emitA(opCode op, Register src1, Register /*src2*/, Register dest,
2327              char *ibuf, Address &base, bool /*noCost*/)
2328 {
2329     //fprintf(stderr,"emitA(op=%d,src1=%d,src2=XX,dest=%d)\n",op,src1,dest);
2330
2331     unsigned char *insn = (unsigned char *) (&ibuf[base]);
2332     unsigned char *first = insn;
2333
2334     switch (op) {
2335     case ifOp: {
2336       // if src1 == 0 jump to dest
2337       // src1 is a temporary
2338       // dest is a target address
2339       emitOpRegReg(0x29, EAX, EAX, insn);           // sub EAX, EAX ; clear EAX
2340       emitOpRegRM(0x3B, EAX, EBP, -(src1*4), insn); // cmp -(src1*4)[EBP], EAX
2341       // je dest
2342       *insn++ = 0x0F;
2343       *insn++ = 0x84;
2344       *((int *)insn) = dest;
2345       insn += sizeof(int);
2346       base += insn-first;
2347       return base;
2348       }
2349     case branchOp: { 
2350         emitJump(dest - JUMP_REL32_SZ, insn); 
2351         base += JUMP_REL32_SZ;
2352         return(base - JUMP_REL32_SZ);
2353       }
2354     case trampTrailer: {
2355       // generate the template for a jump -- actual jump is generated elsewhere
2356       emitJump(0, insn); // jump xxxx
2357       // return the offset of the previous jump
2358       base += insn - first;
2359       return(base - JUMP_REL32_SZ);
2360       }
2361     case trampPreamble: {
2362         base += insn - first;
2363         return(0);      // let's hope this is expected!
2364       }
2365     default:
2366         abort();        // unexpected op for this emit!
2367     }
2368   return(0);            // should never reach here!
2369 }
2370
2371 Register emitR(opCode op, Register src1, Register /*src2*/, Register dest,
2372                char *ibuf, Address &base, bool /*noCost*/,
2373                const instPoint *location)
2374 {
2375     //fprintf(stderr,"emitR(op=%d,src1=%d,src2=XX,dest=%d)\n",op,src1,dest);
2376
2377     unsigned char *insn = (unsigned char *) (&ibuf[base]);
2378     unsigned char *first = insn;
2379
2380     switch (op) {
2381       case getRetValOp: {
2382          // dest is a register where we can store the value
2383          // the return value is in the saved EAX
2384          emitMovRMToReg(EAX, EBP, SAVED_EAX_OFFSET, insn);
2385          emitMovRegToRM(EBP, -(dest*4), EAX, insn);
2386          base += insn - first;
2387          return dest;
2388       }
2389       case getParamOp: {
2390          // src1 is the number of the argument
2391          // dest is a register where we can store the value
2392          // Parameters are addressed by a positive offset from ebp,
2393          // the first is PARAM_OFFSET[ebp]
2394          instPointType ptType = location->getPointType();
2395          if(ptType == callSite) {
2396             emitMovRMToReg(EAX, EBP, CALLSITE_PARAM_OFFSET + src1*4, insn);
2397             emitMovRegToRM(EBP, -(dest*4), EAX, insn);
2398             base += insn - first;
2399             return dest;
2400          } else {
2401             // assert(ptType == functionEntry)
2402             emitMovRMToReg(EAX, EBP, FUNC_PARAM_OFFSET + src1*4, insn);
2403             emitMovRegToRM(EBP, -(dest*4), EAX, insn);
2404             base += insn - first;
2405             return dest;
2406          }
2407       }
2408       default:
2409          abort();                  // unexpected op for this emit!
2410     }
2411     return(Null_Register);        // should never be reached!
2412 }
2413
2414 #ifdef BPATCH_LIBRARY
2415 static inline void emitSHL(Register dest, unsigned char pos, unsigned char *&insn)
2416 {
2417   //fprintf(stderr, "Emiting SHL\n");
2418   *insn++ = 0xC1;
2419   *insn++ = makeModRMbyte(3 /* rm gives register */, 4 /* opcode ext. */, dest);
2420   *insn++ = pos;
2421 }
2422
2423 // VG(8/15/02): Emit the jcc over a conditional snippet
2424 void emitJmpMC(int condition, int offset, char* baseInsn, Address &base)
2425 {
2426   // What we want: 
2427   //   mov eax, [original EFLAGS]
2428   //   push eax
2429   //   popfd
2430   //   jCC target   ; CC = !condition (we jump on the negated condition)
2431
2432   assert(condition >= 0 && condition <= 0x0F);
2433
2434   unsigned char *insn = (unsigned char *) (&baseInsn[base]);
2435   unsigned char *first = insn;
2436
2437   //fprintf(stderr, "OC: %x, NC: %x\n", condition, condition ^ 0x01);
2438   condition ^= 0x01; // flip last bit to negate the tttn condition
2439
2440   emitMovRMToReg(EAX, EBP, SAVED_EFLAGS_OFFSET, insn); // mov eax, offset[ebp]
2441   emitSimpleInsn(0x50, insn);  // push eax
2442   emitSimpleInsn(POPFD, insn); // popfd
2443   emitJcc(condition, offset, insn);
2444   
2445   base += insn-first;
2446 }
2447
2448 // VG(07/30/02): Restore mutatee value of GPR reg to dest (real) GPR
2449 static inline void restoreGPRtoGPR(Register reg, Register dest, unsigned char *&insn)
2450 {
2451   // NOTE: I don't use emitLoadPreviousStackFrameRegister because it saves
2452   // the value to a virtual (stack based) register, which is not what I want!
2453   emitMovRMToReg(dest, EBP, SAVED_EAX_OFFSET-(reg<<2), insn); //mov dest, offset[ebp]
2454 }
2455
2456 // VG(07/30/02): Emit a lea dest, [base + index * scale + disp]; dest is a real GPR
2457 static inline void emitLEA(Register base, Register index, unsigned int scale,
2458                            RegValue disp, Register dest, unsigned char *&insn)
2459 {
2460   *insn++ = 0x8D;
2461   emitAddressingMode(base, index, scale, disp, (int)dest, insn);
2462 }
2463
2464 // VG(11/07/01): Load in destination the effective address given
2465 // by the address descriptor. Used for memory access stuff.
2466 void emitASload(BPatch_addrSpec_NP as, Register dest, char* baseInsn,
2467                 Address &base, bool /* noCost */)
2468 {
2469   unsigned char *insn = (unsigned char *) (&baseInsn[base]);
2470   unsigned char *first = insn;
2471
2472   // TODO 16-bit registers, rep hacks
2473   int imm = as.getImm();
2474   int ra  = as.getReg(0);
2475   int rb  = as.getReg(1);
2476   int sc  = as.getScale();
2477
2478   bool havera = ra > -1, haverb = rb > -1;
2479
2480   // VG(7/30/02): given that we use virtual (stack allocated) registers for
2481   // our inter-snippet temporaries, I assume all real registers to be fair game.
2482   // So, we restore the original registers in EAX and EDX - this allows us to
2483   // generate a lea (load effective address instruction) that will make the cpu
2484   // do the math for us.
2485
2486   // assuming 32-bit addressing (for now)
2487
2488   //fprintf(stderr, "ASLOAD: ra=%d rb=%d sc=%d imm=%d\n", ra, rb, sc, imm);
2489
2490   if(havera)
2491     restoreGPRtoGPR(ra, EAX, insn);        // mov eax, [saved_ra]
2492
2493   if(haverb)
2494     restoreGPRtoGPR(rb, EDX, insn);        // mov edx, [saved_rb]
2495
2496   // Emit the lea to do the math for us:
2497   // e.g. lea eax, [eax + edx * sc + imm] if both ra and rb had to be restored
2498   emitLEA((havera ? EAX : Null_Register), (haverb ? EDX : Null_Register), sc, imm, EAX, insn);
2499
2500   emitMovRegToRM(EBP, -(dest<<2), EAX, insn); // mov (virtual reg) dest, eax
2501   
2502   base += insn - first;
2503 }
2504
2505 void emitCSload(BPatch_addrSpec_NP as, Register dest, char* baseInsn,
2506                 Address &base, bool noCost)
2507 {
2508   // VG(7/30/02): different from ASload on this platform, no LEA business
2509   unsigned char *insn = (unsigned char *) (&baseInsn[base]);
2510   unsigned char *first = insn;
2511
2512   int imm = as.getImm();
2513   int ra  = as.getReg(0);
2514   int rb  = as.getReg(1);
2515   int sc  = as.getScale();
2516
2517   // count is at most 1 register or constant or hack (aka pseudoregister)
2518   assert((ra == -1) && ((rb == -1) || ((imm == 0) && (rb == 1 /*ECX */ || rb >= IA32_EMULATE))));
2519
2520   if(rb >= IA32_EMULATE) {
2521     // TODO: firewall code to ensure that direction is up
2522     bool neg = false;
2523     //fprintf(stderr, "!!!In case rb >= IA32_EMULATE!!!\n");
2524     switch(rb) {
2525     case IA32_NESCAS:
2526       neg = true;
2527     case IA32_ESCAS:
2528       // plan: restore flags, edi, eax, ecx; do rep(n)e scas(b/w); compute (saved_ecx - ecx) << sc;
2529       emitMovRMToReg(EAX, EBP, SAVED_EFLAGS_OFFSET, insn); // mov eax, offset[ebp]
2530       emitSimpleInsn(0x50, insn);  // push eax
2531       emitSimpleInsn(POPFD, insn); // popfd
2532       restoreGPRtoGPR(EAX, EAX, insn);
2533       restoreGPRtoGPR(ECX, ECX, insn);
2534       restoreGPRtoGPR(EDI, EDI, insn);
2535       emitSimpleInsn(neg ? 0xF2 : 0xF3, insn); // rep(n)e
2536       switch(sc) {
2537       case 0:
2538         emitSimpleInsn(0xAE, insn); // scasb
2539         break;
2540       case 1:
2541         emitSimpleInsn(0x66, insn); // operand size override for scasw;
2542       case 2:
2543         emitSimpleInsn(0xAF, insn); // scasw/d
2544         break;
2545       default:
2546         assert(!"Wrong scale!");
2547       }
2548       restoreGPRtoGPR(ECX, EAX, insn); // old ecx -> eax
2549       emitSubRegReg(EAX, ECX, insn); // eax = eax - ecx
2550       if(sc > 0)
2551         emitSHL(EAX, sc, insn);              // shl eax, scale
2552       emitMovRegToRM(EBP, -(dest<<2), EAX, insn); // mov (virtual reg) dest, eax
2553       break;
2554     case IA32_NECMPS:
2555       neg = true;
2556     case IA32_ECMPS:
2557       // plan: restore flags, esi, edi, ecx; do rep(n)e cmps(b/w); compute (saved_ecx - ecx) << sc;
2558       emitMovRMToReg(EAX, EBP, SAVED_EFLAGS_OFFSET, insn); // mov eax, offset[ebp]
2559       emitSimpleInsn(0x50, insn);  // push eax
2560       emitSimpleInsn(POPFD, insn); // popfd
2561       restoreGPRtoGPR(ECX, ECX, insn);
2562       restoreGPRtoGPR(ESI, ESI, insn);
2563       restoreGPRtoGPR(EDI, EDI, insn);
2564       emitSimpleInsn(neg ? 0xF2 : 0xF3, insn); // rep(n)e
2565       switch(sc) {
2566       case 0:
2567         emitSimpleInsn(0xA6, insn); // cmpsb
2568         break;
2569       case 1:
2570         emitSimpleInsn(0x66, insn); // operand size override for cmpsw;
2571       case 2:
2572         emitSimpleInsn(0xA7, insn); // cmpsw/d
2573         break;
2574       default:
2575         assert(!"Wrong scale!");
2576       }
2577       restoreGPRtoGPR(ECX, EAX, insn); // old ecx -> eax
2578       emitSubRegReg(EAX, ECX, insn); // eax = eax - ecx
2579       if(sc > 0)
2580         emitSHL(EAX, sc, insn);              // shl eax, scale
2581       emitMovRegToRM(EBP, -(dest<<2), EAX, insn); // mov (virtual reg) dest, eax
2582       break;
2583     default:
2584       assert(!"Wrong emulation!");
2585     }
2586   }
2587   else if(rb > -1) {
2588     //fprintf(stderr, "!!!In case rb > -1!!!\n");
2589     // TODO: 16-bit pseudoregisters
2590     assert(rb < 8); 
2591     restoreGPRtoGPR(rb, EAX, insn);        // mov eax, [saved_rb]
2592     if(sc > 0)
2593       emitSHL(EAX, sc, insn);              // shl eax, scale
2594     emitMovRegToRM(EBP, -(dest<<2), EAX, insn); // mov (virtual reg) dest, eax
2595   }
2596   else
2597     emitMovImmToRM(EBP, -(dest<<2), imm, insn);
2598
2599   base += insn - first;
2600 }
2601 #endif
2602
2603
2604 void emitVload(opCode op, Address src1, Register /*src2*/, Register dest, 
2605              char *ibuf, Address &base, bool /*noCost*/, int /* size */)
2606 {
2607     unsigned char *insn = (unsigned char *) (&ibuf[base]);
2608     unsigned char *first = insn;
2609
2610     if (op == loadConstOp) {
2611       // dest is a temporary
2612       // src1 is an immediate value 
2613       // dest = src1:imm32
2614       emitMovImmToRM(EBP, -(dest*4), src1, insn);
2615       base += insn - first;
2616       return;
2617     } else if (op ==  loadOp) {
2618       // dest is a temporary
2619       // src1 is the address of the operand
2620       // dest = [src1]
2621       emitMovMToReg(EAX, src1, insn);               // mov eax, src1
2622       emitMovRegToRM(EBP, -(dest*4), EAX, insn);    // mov -(dest*4)[ebp], eax
2623       base += insn - first;
2624       return;
2625     } else if (op == loadFrameRelativeOp) {
2626       // dest is a temporary
2627       // src1 is the offset of the from the frame of the variable
2628       // eax = [eax]    - saved sp
2629       // dest = [eax](src1)
2630       emitMovRMToReg(EAX, EBP, 0, insn);       // mov (%ebp), %eax 
2631       emitMovRMToReg(EAX, EAX, src1, insn);    // mov <offset>(%eax), %eax 
2632       emitMovRegToRM(EBP, -(dest*4), EAX, insn);    // mov -(dest*4)[ebp], eax
2633       base += insn - first;
2634       return;
2635     } else if (op == loadFrameAddr) {
2636       emitMovRMToReg(EAX, EBP, 0, insn);       // mov (%ebp), %eax 
2637       emitAddRegImm32(EAX, src1, insn);        // add #<offset>, %eax
2638       emitMovRegToRM(EBP, -(dest*4), EAX, insn);    // mov -(dest*4)[ebp], eax
2639       base += insn - first;
2640       return;
2641     } else {
2642         abort();                // unexpected op for this emit!
2643     }
2644 }
2645
2646 void emitVstore(opCode op, Register src1, Register src2, Address dest,
2647              char *ibuf, Address &base, bool /*noCost*/, int /* size */)
2648 {
2649     unsigned char *insn = (unsigned char *) (&ibuf[base]);
2650     unsigned char *first = insn;
2651
2652     if (op ==  storeOp) {
2653       // [dest] = src1
2654       // dest has the address where src1 is to be stored
2655       // src1 is a temporary
2656       // src2 is a "scratch" register, we don't need it in this architecture
2657       emitMovRMToReg(EAX, EBP, -(src1*4), insn);    // mov eax, -(src1*4)[ebp]
2658
2659       emitMovRegToM(dest, EAX, insn);               // mov dest, eax
2660       base += insn - first;
2661       return;
2662     } else if (op == storeFrameRelativeOp) {
2663       // src1 is a temporary
2664       // src2 is a "scratch" register, we don't need it in this architecture
2665       // dest is the frame offset 
2666       //
2667       // src2 = [ebp]   - saved sp
2668       // (dest)[src2] = src1
2669       emitMovRMToReg(src2, EBP, 0, insn);           // mov src2, (ebp)
2670       emitMovRMToReg(EAX, EBP, -(src1*4), insn);    // mov eax, -(src1*4)[ebp]
2671       emitMovRegToRM(src2, dest, EAX, insn);        // mov (dest)[src2], eax
2672       base += insn - first;
2673       return;
2674     } else {
2675         abort();                // unexpected op for this emit!
2676     }
2677 }
2678
2679 void emitVupdate(opCode op, RegValue src1, Register /*src2*/, Address dest, 
2680              char *ibuf, Address &base, bool noCost)
2681 {
2682     unsigned char *insn = (unsigned char *) (&ibuf[base]);
2683     unsigned char *first = insn;
2684
2685     if (op == updateCostOp) {
2686       // src1 is the cost value
2687       // src2 is not used
2688       // dest is the address of observed cost
2689
2690       if (!noCost) {
2691          // update observed cost
2692          // dest = address of DYNINSTobsCostLow
2693          // src1 = cost
2694          emitAddMemImm32(dest, src1, insn);  // ADD (dest), src1
2695       }
2696       base += insn-first;
2697       return;           //return base;    // never seem to ever need this
2698     } else {
2699         abort();                // unexpected op for this emit!
2700     }
2701 }
2702
2703 void emitV(opCode op, Register src1, Register src2, Register dest, 
2704              char *ibuf, Address &base, bool /*noCost*/, int /* size */,
2705              const instPoint * /* location */, process * /* proc */,
2706              registerSpace * /* rs */ )
2707 {
2708     //fprintf(stderr,"emitV(op=%d,src1=%d,src2=%d,dest=%d)\n",op,src1,src2,dest);
2709
2710     assert ((op!=branchOp) && (op!=ifOp) &&
2711             (op!=trampTrailer) && (op!=trampPreamble));         // !emitA
2712     assert ((op!=getRetValOp) && (op!=getParamOp));             // !emitR
2713     assert ((op!=loadOp) && (op!=loadConstOp));                 // !emitVload
2714     assert ((op!=storeOp));                                     // !emitVstore
2715     assert ((op!=updateCostOp));                                // !emitVupdate
2716
2717     unsigned char *insn = (unsigned char *) (&ibuf[base]);
2718     unsigned char *first = insn;
2719
2720     if (op ==  loadIndirOp) {
2721       // same as loadOp, but the value to load is already in a register
2722       emitMovRMToReg(EAX, EBP, -(src1*4), insn); // mov eax, -(src1*4)[ebp]
2723       emitMovRMToReg(EAX, EAX, 0, insn);         // mov eax, [eax]
2724       emitMovRegToRM(EBP, -(dest*4), EAX, insn); // mov -(dest*4)[ebp], eax
2725
2726     } 
2727     else if (op ==  storeIndirOp) {
2728       // same as storeOp, but the address where to store is already in a
2729       // register
2730       emitMovRMToReg(EAX, EBP, -(src1*4), insn);   // mov eax, -(src1*4)[ebp]
2731       emitMovRMToReg(ECX, EBP, -(dest*4), insn);   // mov ecx, -(dest*4)[ebp]
2732       emitMovRegToRM(ECX, 0, EAX, insn);           // mov [ecx], eax
2733
2734     } else if (op == noOp) {
2735        emitSimpleInsn(NOP, insn); // nop
2736
2737     } else if (op == saveRegOp) {
2738       // should not be used on this platform
2739       assert(0);
2740
2741     } else {
2742       unsigned opcode = 0;//initialize to placate gcc warnings
2743         switch (op) {
2744             // integer ops
2745             case plusOp:
2746                 // dest = src1 + src2
2747                 // mv eax, src1
2748                 // add eax, src2
2749                 // mov dest, eax
2750                 opcode = 0x03; // ADD
2751                 break;
2752
2753             case minusOp:
2754                 opcode = 0x2B; // SUB
2755                 break;
2756
2757             case timesOp:
2758                 opcode = 0x0FAF; // IMUL
2759                 break;
2760
2761             case divOp:
2762                 // dest = src1 div src2
2763                 // mov eax, src1
2764                 // cdq   ; edx = sign extend of eax
2765                 // idiv eax, src2 ; eax = edx:eax div src2, edx = edx:eax mod src2
2766                 // mov dest, eax
2767                 emitMovRMToReg(EAX, EBP, -(src1*4), insn);
2768                 emitSimpleInsn(0x99, insn);
2769                 emitOpRegRM(0xF7, 0x7 /*opcode extension*/, EBP, -(src2*4), insn);
2770                 emitMovRegToRM(EBP, -(dest*4), EAX, insn);
2771                 base += insn-first;
2772                 return;
2773                 break;
2774
2775             // Bool ops
2776             case orOp:
2777                 opcode = 0x0B; // OR 
2778                 break;
2779
2780             case andOp:
2781                 opcode = 0x23; // AND
2782                 break;
2783
2784             // rel ops
2785             // dest = src1 relop src2
2786             case eqOp:
2787             case neOp:
2788             case lessOp:
2789             case leOp:
2790             case greaterOp:
2791             case geOp:
2792                 emitRelOp(op, dest, src1, src2, insn);
2793                 base += insn-first;
2794                 return;
2795                 break;
2796
2797             default:
2798                 abort();
2799                 break;
2800         }
2801
2802         emitMovRMToReg(EAX, EBP, -(src1*4), insn);
2803         emitOpRegRM(opcode, EAX, EBP, -(src2*4), insn);
2804         emitMovRegToRM(EBP, -(dest*4), EAX, insn);
2805       }
2806     base += insn - first;
2807     return;
2808 }
2809
2810
2811 void emitImm(opCode op, Register src1, RegValue src2imm, Register dest, 
2812              char *ibuf, Address &base, bool)
2813 {
2814     unsigned char *insn = (unsigned char *) (&ibuf[base]);
2815     unsigned char *first = insn;
2816
2817     if (op ==  storeOp) {
2818       // [dest] = src1
2819       // dest has the address where src1 is to be stored
2820       // src1 is an immediate value
2821       // src2 is a "scratch" register, we don't need it in this architecture
2822       emitMovImmToReg(EAX, dest, insn);
2823       emitMovImmToRM(EAX, 0, src1, insn);
2824     } else {
2825         unsigned opcode1;
2826         unsigned opcode2;
2827         switch (op) {
2828             // integer ops
2829             case plusOp:
2830                 opcode1 = 0x81;
2831                 opcode2 = 0x0; // ADD
2832                 break;
2833
2834             case minusOp:
2835                 opcode1 = 0x81;
2836                 opcode2 = 0x5; // SUB
2837                 break;
2838
2839             case timesOp: {
2840                 int result=-1;
2841                 if (isPowerOf2(src2imm, result) && result <= MAX_IMM8) {
2842                   if (src1 != dest) {
2843                     emitMovRMToReg(EAX, EBP, -(src1*4), insn);
2844                     emitMovRegToRM(EBP, -(dest*4), EAX, insn);
2845                   }
2846                   // sal dest, result
2847                   emitOpRMImm8(0xC1, 4, EBP, -(dest*4), result, insn);
2848                 }
2849                 else {
2850                   // imul EAX, -(src1*4)[ebp], src2imm
2851                   emitOpRegRMImm(0x69, EAX, EBP, -(src1*4), src2imm, insn);
2852                   emitMovRegToRM(EBP, -(dest*4), EAX, insn);
2853                 } 
2854                 base += insn-first;
2855                 return;
2856               }
2857                 break;
2858
2859             case divOp: {
2860                 int result=-1;
2861                 if (isPowerOf2(src2imm, result) && result <= MAX_IMM8) {
2862                   if (src1 != dest) {
2863                     emitMovRMToReg(EAX, EBP, -(src1*4), insn);
2864                     emitMovRegToRM(EBP, -(dest*4), EAX, insn);
2865                   }
2866                   // sar dest, result
2867                   emitOpRMImm8(0xC1, 7, EBP, -(dest*4), result, insn);
2868                 }
2869                 else {
2870                   // dest = src1 div src2imm
2871                   // mov eax, src1
2872                   // cdq   ; edx = sign extend of eax
2873                   // mov ebx, src2imm
2874                   // idiv eax, ebx ; eax = edx:eax div src2, edx = edx:eax mod src2
2875                   // mov dest, eax
2876                   emitMovRMToReg(EAX, EBP, -(src1*4), insn);
2877                   emitSimpleInsn(0x99, insn);
2878                   emitMovImmToReg(EBX, src2imm, insn);
2879                   // idiv eax, ebx
2880                   emitOpRegReg(0xF7, 0x7 /*opcode extension*/, EBX, insn); 
2881                   emitMovRegToRM(EBP, -(dest*4), EAX, insn);
2882                 }
2883               }
2884                 base += insn-first;
2885                 return;
2886                 break;
2887
2888             // Bool ops
2889             case orOp:
2890                 opcode1 = 0x81;
2891                 opcode2 = 0x1; // OR 
2892                 break;
2893
2894             case andOp:
2895                 opcode1 = 0x81;
2896                 opcode2 = 0x4; // AND
2897                 break;
2898
2899             // rel ops
2900             // dest = src1 relop src2
2901             case eqOp:
2902             case neOp:
2903             case lessOp:
2904             case leOp:
2905             case greaterOp:
2906             case geOp:
2907                 emitRelOpImm(op, dest, src1, src2imm, insn);
2908                 base += insn-first;
2909                 return;
2910                 break;
2911
2912             default:
2913                 abort();
2914                 break;
2915         }
2916         if (src1 != dest) {
2917           emitMovRMToReg(EAX, EBP, -(src1*4), insn);
2918           emitMovRegToRM(EBP, -(dest*4), EAX, insn);
2919         }
2920         emitOpRMImm(opcode1, opcode2, EBP, -(dest*4), src2imm, insn);
2921       }
2922     base += insn - first;
2923     return;
2924 }
2925
2926
2927
2928 int getInsnCost(opCode op)
2929 {
2930     if (op == loadConstOp) {
2931         return(1);
2932     } else if (op ==  loadOp) {
2933         return(1+1);
2934     } else if (op ==  loadIndirOp) {
2935         return(3);
2936     } else if (op ==  storeOp) {
2937         return(1+1); 
2938     } else if (op ==  storeIndirOp) {
2939         return(3);
2940     } else if (op ==  ifOp) {
2941         return(1+2+1);
2942     } else if (op ==  ifMCOp) { // VG(8/15/02): No clue if this is right or not
2943         return(1+2+1);
2944     } else if (op ==  whileOp) {
2945         return(1+2+1+1); /* Need to find out about this */
2946     } else if (op == branchOp) {
2947         return(1);      /* XXX Need to find out what value this should be. */
2948     } else if (op ==  callOp) {
2949         // cost of call only
2950         return(1+2+1+1);
2951     } else if (op == funcJumpOp) {
2952         // copy callOp
2953         return(1+2+1+1);
2954     } else if (op == updateCostOp) {
2955         return(3);
2956     } else if (op ==  trampPreamble) {
2957         return(0);
2958     } else if (op ==  trampTrailer) {
2959         return(1);
2960     } else if (op == noOp) {
2961         return(1);
2962     } else if (op == getRetValOp) {
2963         return (1+1);
2964     } else if (op == getParamOp) {
2965         return(1+1);
2966     } else {
2967         switch (op) {
2968             // rel ops
2969             case eqOp:
2970             case neOp:
2971             case lessOp:
2972             case leOp:
2973             case greaterOp:
2974             case geOp:
2975                 return(1+1+2+1+1+1);
2976                 break;
2977             case divOp:
2978                 return(1+2+46+1);
2979             case timesOp:
2980                 return(1+10+1);
2981             case plusOp:
2982             case minusOp:
2983             case orOp:
2984             case andOp:
2985                 return(1+2+1);
2986             case getAddrOp:
2987                 return(0);      // doesn't add anything to operand
2988             default:
2989                 assert(0);
2990                 return 0;
2991                 break;
2992         }
2993     }
2994 }
2995
2996
2997
2998 bool process::heapIsOk(const pdvector<sym_data> &find_us) {
2999   Symbol sym;
3000   string str;
3001   Address baseAddr;
3002
3003   // find the main function
3004   // first look for main or _main
3005 #if !defined(i386_unknown_nt4_0)
3006   if (!((mainFunction = findOneFunction("main")) 
3007         || (mainFunction = findOneFunction("_main")))) {
3008      string msg = "Cannot find main. Exiting.";
3009      statusLine(msg.c_str());
3010      showErrorCallback(50, msg);
3011      return false;
3012   }
3013 #else
3014   if (!((mainFunction = findOneFunction("main")) 
3015         || (mainFunction = findOneFunction("_main"))
3016         || (mainFunction = findOneFunction("WinMain"))
3017         || (mainFunction = findOneFunction("_WinMain"))
3018         || (mainFunction = findOneFunction("wWinMain"))
3019         || (mainFunction = findOneFunction("_wWinMain")))) {
3020      string msg = "Cannot find main or WinMain. Exiting.";
3021      statusLine(msg.c_str());
3022      showErrorCallback(50, msg);
3023      return false;
3024   }
3025 #endif
3026
3027   for (unsigned i=0; i<find_us.size(); i++) {
3028     str = find_us[i].name;
3029     if (!getSymbolInfo(str, sym, baseAddr)) {
3030       string str1 = string("_") + str.c_str();
3031       if (!getSymbolInfo(str1, sym, baseAddr) && find_us[i].must_find) {
3032         string msg;
3033         msg = string("Cannot find ") + str + string(". Exiting");
3034         statusLine(msg.c_str());
3035         showErrorCallback(50, msg);
3036         return false;
3037       }
3038     }
3039   }
3040
3041 //  string ghb = GLOBAL_HEAP_BASE;
3042 //  if (!getSymbolInfo(ghb, sym, baseAddr)) {
3043 //    ghb = U_GLOBAL_HEAP_BASE;
3044 //    if (!getSymbolInfo(ghb, symm baseAddr)) {
3045 //      string msg;
3046 //      msg = string("Cannot find ") + str + string(". Exiting");
3047 //      statusLine(msg.c_str());
3048 //      showErrorCallback(50, msg);
3049 //      return false;
3050 //    }
3051 //  }
3052 //  Address instHeapEnd = sym.addr()+baseAddr;
3053 //  addInternalSymbol(ghb, instHeapEnd);
3054
3055 #if !defined(i386_unknown_nt4_0)
3056   string tt = "DYNINSTtrampTable";
3057   if (!getSymbolInfo(tt, sym, baseAddr)) {
3058       string msg;
3059       msg = string("Cannot find ") + tt + string(". Cannot use this application");
3060       statusLine(msg.c_str());
3061       showErrorCallback(50, msg);
3062       return false;
3063   }
3064 #endif
3065
3066   return true;
3067 }
3068
3069
3070
3071 dictionary_hash<string, unsigned> funcFrequencyTable(string::hash);
3072
3073 //
3074 // initDefaultPointFrequencyTable - define the expected call frequency of
3075 //    procedures.  Currently we just define several one shots with a
3076 //    frequency of one, and provide a hook to read a file with more accurate
3077 //    information.
3078 //
3079 void initDefaultPointFrequencyTable()
3080 {
3081     FILE *fp;
3082     float value;
3083     char name[512];
3084
3085     funcFrequencyTable["main"] = 1;
3086     funcFrequencyTable["DYNINSTsampleValues"] = 1;
3087     funcFrequencyTable[EXIT_NAME] = 1;
3088
3089     // try to read file.
3090     fp = fopen("freq.input", "r");
3091     if (!fp) {
3092         return;
3093     } else {
3094         printf("found freq.input file\n");
3095     }
3096     while (!feof(fp)) {
3097         fscanf(fp, "%s %f\n", name, &value);
3098         funcFrequencyTable[name] = (int) value;
3099         printf("adding %s %f\n", name, value);
3100     }
3101     fclose(fp);
3102 }
3103
3104 /*
3105  * Get an estimate of the frequency for the passed instPoint.  
3106  *    This is not (always) the same as the function that contains the point.
3107  * 
3108  *  The function is selected as follows:
3109  *
3110  *  If the point is an entry or an exit return the function name.
3111  *  If the point is a call and the callee can be determined, return the called
3112  *     function.
3113  *  else return the funcation containing the point.
3114  *
3115  *  WARNING: This code contains arbitrary values for func frequency (both user 
3116  *     and system).  This should be refined over time.
3117  *
3118  * Using 1000 calls sec to be one SD from the mean for most FPSPEC apps.
3119  *      -- jkh 6/24/94
3120  *
3121  */
3122 float getPointFrequency(instPoint *point)
3123 {
3124
3125     pd_Function *func = point->callee();
3126
3127     if (!func)
3128       func = point->func();
3129
3130     if (!funcFrequencyTable.defines(func->prettyName())) {
3131       // Changing this value from 250 to 100 because predictedCost was
3132       // too high - naim 07/18/96
3133       return(100.0);       
3134     } else {
3135       return ((float)funcFrequencyTable[func->prettyName()]);
3136     }
3137 }
3138
3139 //
3140 // return cost in cycles of executing at this point.  This is the cost
3141 //   of the base tramp if it is the first at this point or 0 otherwise.
3142 //
3143 int getPointCost(process *proc, const instPoint *point)
3144 {
3145     if (proc->baseMap.defines(point)) {
3146         return(0);
3147     } else {
3148         if (point->usesTrap(proc))
3149           return 9000; // estimated number of cycles for traps
3150         else
3151           return(83);
3152     }
3153 }
3154
3155
3156
3157 bool returnInstance::checkReturnInstance(const pdvector<pdvector<Frame> >&stackWalks)
3158 {
3159     for (unsigned walk_iter = 0; walk_iter < stackWalks.size(); walk_iter++)
3160         for (u_int i=0; i < stackWalks[walk_iter].size(); i++) {
3161             // 27FEB03: we no longer return true if we are at the 
3162             // exact same address as the return instance. In this case
3163             // writing a jump is safe. -- bernat
3164             if ((stackWalks[walk_iter][i].getPC() > addr_) && 
3165                 (stackWalks[walk_iter][i].getPC() < addr_+size_)) 
3166             {
3167                 fprintf(stderr, "PC at 0x%x (thread %d, frame %d) conflicts with inst point 0x%x\n",
3168                         stackWalks[walk_iter][i].getPC(), walk_iter, i, addr_);
3169                 return false;
3170             }
3171         }  
3172     return true;
3173 }
3174  
3175 void returnInstance::installReturnInstance(process *proc) {
3176     assert(instructionSeq);
3177     proc->writeTextSpace((void *)addr_, instSeqSize, instructionSeq->ptr());
3178     delete instructionSeq;
3179     instructionSeq = 0;
3180         installed = true;
3181 }
3182
3183 void returnInstance::addToReturnWaitingList(Address , process *) {
3184     //P_abort();
3185         assert(0);
3186 }
3187
3188 void generateBreakPoint(instruction &insn) {
3189   insn = instruction ((const unsigned char*)"\017\013", ILLEGAL, 2);
3190 }
3191
3192 void instWaitingList::cleanUp(process *, Address ) {
3193   P_abort();
3194 /*
3195   proc->writeTextSpace((caddr_t)pc, relocatedInstruction.size(),
3196             (caddr_t&)(relocatedInstruction.ptr()));
3197   proc->writeTextSpace((caddr_t)addr_, instSeqSize,
3198             (caddr_t)instructionSeq);
3199 */
3200 }
3201
3202 /* ***************************************************** */
3203
3204 bool rpcMgr::emitInferiorRPCheader(void *void_insnPtr, Address &baseBytes, bool /*isFunclet*/) 
3205 {
3206    unsigned char *insnPtr = (unsigned char *)void_insnPtr;
3207    unsigned char *origInsnPtr = insnPtr;
3208    insnPtr += baseBytes;
3209
3210    // We emit the following here (to set up a fresh stack frame):
3211    // pushl %ebp        (0x55)
3212    // movl  %esp, %ebp  (0x89 0xe5)
3213    // pushad
3214    // pushfd
3215
3216    emitSimpleInsn(PUSHFD, insnPtr);
3217    emitSimpleInsn(PUSHAD, insnPtr);
3218    emitSimpleInsn(PUSH_EBP, insnPtr);
3219    emitMovRegToReg(EBP, ESP, insnPtr);
3220
3221    // allocate space for temporaries (virtual registers)
3222    emitOpRegImm(5, ESP, 128, insnPtr); // sub esp, 128
3223
3224    baseBytes += (insnPtr - origInsnPtr);
3225
3226    return true;
3227 }
3228
3229 bool rpcMgr::emitInferiorRPCtrailer(void *void_insnPtr, Address &baseBytes,
3230                                     unsigned &breakOffset,
3231                                     bool shouldStopForResult,
3232                                     unsigned &stopForResultOffset,
3233                                     unsigned &justAfter_stopForResultOffset,
3234                                     bool /*isFunclet*/)
3235 {
3236    unsigned char *insnPtr = (unsigned char *)void_insnPtr;
3237
3238    // unsigned char * is the most natural to work with on x86, since 
3239    // instructions are always an integral # of bytes.  Besides, it makes 
3240    // the following line easy:
3241    insnPtr += baseBytes; // start off in the right spot
3242
3243    if (shouldStopForResult) {
3244       // illegal insn: 0x0f0b does the trick.
3245       stopForResultOffset = baseBytes;
3246       *insnPtr++ = 0x0f;
3247       *insnPtr++ = 0x0b;
3248       baseBytes += 2;
3249
3250       justAfter_stopForResultOffset = baseBytes;
3251    }
3252
3253    // Sequence: popfd, popad, leave (0xc9), call DYNINSTbreakPoint(), illegal
3254
3255    emitSimpleInsn(LEAVE, insnPtr); // leave
3256    emitSimpleInsn(POPAD, insnPtr); // popad
3257    emitSimpleInsn(POPFD, insnPtr); // popfd
3258    baseBytes += 3; // all simple insns are 1 byte
3259
3260    // We can't do a SIGTRAP since SIGTRAP is reserved in x86.
3261    // So we do a SIGILL instead.
3262    breakOffset = baseBytes;
3263    *insnPtr++ = 0x0f;
3264    *insnPtr++ = 0x0b;
3265    baseBytes += 2;
3266
3267    // Here, we should generate an illegal insn, or something.
3268    // A two-byte insn, 0x0f0b, should do the trick.  The idea is that
3269    // the code should never be executed.
3270    *insnPtr++ = 0x0f;
3271    *insnPtr++ = 0x0b;
3272    baseBytes += 2;
3273
3274    return true;
3275 }
3276
3277 // process::replaceFunctionCall
3278 //
3279 // Replace the function call at the given instrumentation point with a call to
3280 // a different function, or with a NOOP.  In order to replace the call with a
3281 // NOOP, pass NULL as the parameter "func."
3282 // Returns true if sucessful, false if not.  Fails if the site is not a call
3283 // site, or if the site has already been instrumented using a base tramp.
3284 //
3285 // Note that right now we can only replace a call instruction that is five
3286 // bytes long (like a call to a 32-bit relative address).
3287 bool process::replaceFunctionCall(const instPoint *point,
3288                                   const function_base *func) {
3289     // Must be a call site
3290     if (!point->insnAtPoint().isCall())
3291         return false;
3292
3293     // Cannot already be instrumented with a base tramp
3294     if (baseMap.defines(point))
3295         return false;
3296
3297     // Replace the call
3298     if (func == NULL) { // Replace with NOOPs
3299         unsigned char *newInsn = new unsigned char[point->insnAtPoint().size()];
3300         unsigned char *p = newInsn;
3301         for (unsigned i = 0; i < point->insnAtPoint().size(); i++)
3302             emitSimpleInsn(NOP, p);
3303         writeTextSpace((void *)point->iPgetAddress(),
3304                        point->insnAtPoint().size(), newInsn);
3305     } else { // Replace with a call to a different function
3306         // XXX Right only, call has to be 5 bytes -- sometime, we should make
3307         // it work for other calls as well.
3308         assert(point->insnAtPoint().size() == CALL_REL32_SZ);
3309         unsigned char *newInsn = new unsigned char[CALL_REL32_SZ];
3310         unsigned char *p = newInsn;
3311         emitCallRel32(func->addr() - (point->iPgetAddress()+CALL_REL32_SZ), p);
3312         writeTextSpace((void *)point->iPgetAddress(), CALL_REL32_SZ, newInsn);
3313     }
3314
3315     return true;
3316 }
3317
3318 // Emit code to jump to function CALLEE without linking.  (I.e., when
3319 // CALLEE returns, it returns to the current caller.)
3320 void emitFuncJump(opCode op, 
3321                   char *i, Address &base, 
3322                   const function_base *callee, process *proc,
3323                   const instPoint *loc, bool noCost)
3324 {
3325        assert(op == funcJumpOp);
3326
3327        Address addr = callee->getEffectiveAddress(proc);
3328        unsigned char *insn = (unsigned char *) &i[base];
3329        unsigned char *first = insn;
3330
3331        if (loc->isConservative())
3332           emitOpRegRM(FRSTOR, FRSTOR_OP, EBP, -128 - FSAVE_STATE_SIZE, insn);
3333        emitSimpleInsn(LEAVE, insn);     // leave
3334        emitSimpleInsn(POPAD, insn);     // popad
3335        if (!loc->isConservative() || noCost)
3336           emitSimpleInsn(POPFD, insn);     // popfd
3337
3338        *insn++ = 0x68; /* push 32 bit immediate */
3339        *((int *)insn) = addr; /* the immediate */
3340        insn += 4;
3341        *insn++ = 0xc3; /* ret */
3342
3343        base += (insn-first);
3344 }
3345
3346 void emitLoadPreviousStackFrameRegister(Address register_num,
3347                                         Register dest,
3348                                         char *insn,
3349                                         Address &base,
3350                                         int,
3351                                         bool){
3352   //Previous stack frame register is stored on the stack,
3353   //it was stored there at the begining of the base tramp.
3354
3355   //Calculate the register's offset from the frame pointer in EBP
3356   unsigned offset = SAVED_EAX_OFFSET - (register_num * 4);
3357   
3358   unsigned char *in = (unsigned char *) (&insn[base]);
3359   unsigned char *first = in;
3360   
3361   emitMovRMToReg(EAX, EBP, offset, in); //mov eax, offset[ebp]
3362   emitMovRegToRM(EBP, -(dest*4), EAX, in); //mov dest, 0[eax]
3363   base += in - first;
3364 }
3365
3366
3367 #ifndef BPATCH_LIBRARY
3368 bool process::isDynamicCallSite(instPoint *callSite){
3369   function_base *temp;
3370   if(!findCallee(*(callSite),temp)){
3371     return true;
3372   }
3373   return false;
3374 }
3375
3376 bool process::MonitorCallSite(instPoint *callSite){
3377   Register base_reg, index_reg;
3378   int displacement;
3379   unsigned scale;
3380   int addr_mode;
3381   unsigned Mod;
3382
3383   AstNode *func;
3384   instruction i = callSite->insnAtPoint();
3385   pdvector<AstNode *> the_args(2);
3386   if(i.isCallIndir()){
3387     addr_mode = get_instruction_operand(i.ptr(), base_reg, index_reg,
3388                                          displacement, scale, Mod);
3389     switch(addr_mode){
3390       
3391     case REGISTER_DIRECT:
3392       {
3393       the_args[0] = new AstNode(AstNode::PreviousStackFrameDataReg,
3394                                 (void *) base_reg);
3395       the_args[1] = new AstNode(AstNode::Constant,
3396                                 (void *) callSite->iPgetAddress());
3397       func = new AstNode("DYNINSTRegisterCallee", the_args);
3398       miniTrampHandle mtHandle;
3399       addInstFunc(&mtHandle, this, callSite, func, callPreInsn,
3400                   orderFirstAtPoint, true,false);
3401       break;
3402       }
3403     case REGISTER_INDIRECT:
3404       {
3405         AstNode *prevReg = new AstNode(AstNode::PreviousStackFrameDataReg,
3406                                        (void *) base_reg);
3407         the_args[0] = new AstNode(AstNode::DataIndir, prevReg);
3408         the_args[1] = new AstNode(AstNode::Constant,
3409                                   (void *) callSite->iPgetAddress());
3410         func = new AstNode("DYNINSTRegisterCallee", the_args);
3411         miniTrampHandle mtHandle;
3412         addInstFunc(&mtHandle, this, callSite, func, callPreInsn,
3413                     orderFirstAtPoint, true,false);
3414         break;
3415       }
3416     case REGISTER_INDIRECT_DISPLACED:
3417       {
3418         AstNode *prevReg = new AstNode(AstNode::PreviousStackFrameDataReg,
3419                                        (void *) base_reg);
3420         AstNode *derefPrevReg = new AstNode(AstNode::DataIndir, prevReg );
3421
3422         AstNode *offset = new AstNode(AstNode::Constant, 
3423                                       (void *) displacement);
3424         AstNode *sum = new AstNode(plusOp, derefPrevReg, offset);
3425         
3426         the_args[0] = new AstNode(AstNode::DataIndir, sum);
3427         the_args[1] = new AstNode(AstNode::Constant,
3428                                   (void *) callSite->iPgetAddress());
3429         func = new AstNode("DYNINSTRegisterCallee", the_args);
3430         miniTrampHandle mtHandle;
3431         addInstFunc(&mtHandle, this, callSite, func, callPreInsn,
3432                     orderFirstAtPoint, true,false);
3433         break;
3434       }
3435     case DISPLACED: 
3436       {
3437         AstNode *offset = new AstNode(AstNode::Constant, 
3438                                       (void *) displacement);
3439         the_args[0] = new AstNode(AstNode::DataIndir, offset);
3440         the_args[1] = new AstNode(AstNode::Constant,
3441                                   (void *) callSite->iPgetAddress());
3442         func = new AstNode("DYNINSTRegisterCallee", the_args);
3443         miniTrampHandle mtHandle;
3444         addInstFunc(&mtHandle, this, callSite, func, callPreInsn,
3445                     orderFirstAtPoint, true, false);
3446         break;
3447       }
3448     case SIB:
3449       {
3450         AstNode *effective_address;
3451         if(index_reg != 4) { //We use a scaled index
3452           bool useBaseReg = true;
3453           if(Mod == 0 && base_reg == 5){
3454             cerr << "Inserting untested call site monitoring "
3455               "instrumentation at address " << hex << 
3456               callSite->iPgetAddress() << dec << endl;
3457             useBaseReg = false;
3458           }
3459           
3460           AstNode *index = new AstNode(AstNode::PreviousStackFrameDataReg,
3461                                        (void *) index_reg);
3462           AstNode *base = new AstNode(AstNode::PreviousStackFrameDataReg,
3463                                       (void *) base_reg);
3464           
3465           AstNode *disp = new AstNode(AstNode::Constant, 
3466                                       (void *) displacement);
3467           
3468           if(scale == 1){ //No need to do the multiplication
3469             if(useBaseReg){
3470               AstNode *base_index_sum = new AstNode(plusOp, index, base);
3471               effective_address = new AstNode(plusOp, base_index_sum,
3472                                               disp);
3473             }
3474             else 
3475               effective_address = new AstNode(plusOp, index, disp); 
3476             
3477             the_args[0] = new AstNode(AstNode::DataIndir, effective_address);
3478             
3479             the_args[1] = new AstNode(AstNode::Constant,
3480                                       (void *) callSite->iPgetAddress());
3481             func = new AstNode("DYNINSTRegisterCallee", the_args);
3482             miniTrampHandle mtHandle;
3483             addInstFunc(&mtHandle, this, callSite, func, callPreInsn,
3484                         orderFirstAtPoint, true, false);
3485           }
3486           else {
3487             AstNode *scale_factor
3488               = new AstNode(AstNode::Constant, (void *) scale);
3489             AstNode *index_scale_product = new AstNode(timesOp, index, 
3490                                                        scale_factor);
3491             if(useBaseReg){
3492               AstNode *base_index_sum = new AstNode(plusOp, 
3493                                                     index_scale_product,
3494                                                     base);
3495               effective_address = new AstNode(plusOp, base_index_sum,
3496                                               disp);
3497             }
3498             else 
3499               effective_address = new AstNode(plusOp, 
3500                                                index_scale_product,
3501                                                disp);
3502             the_args[0] = new AstNode(AstNode::DataIndir, effective_address);
3503             
3504             the_args[1] = new AstNode(AstNode::Constant,
3505                                       (void *) callSite->iPgetAddress());
3506             func = new AstNode("DYNINSTRegisterCallee", the_args);
3507             miniTrampHandle mtHandle;       
3508             addInstFunc(&mtHandle, this, callSite, func, callPreInsn,
3509                         orderFirstAtPoint, true,false);
3510           }
3511         }
3512         else { //We do not use a scaled index. 
3513           cerr << "Inserting untested call site monitoring "
3514             "instrumentation at address " << hex <<
3515             callSite->iPgetAddress() << dec << endl;
3516           AstNode *base = new AstNode(AstNode::PreviousStackFrameDataReg,
3517                                       (void *) base_reg);
3518           AstNode *disp = new AstNode(AstNode::Constant, 
3519                                       (void *) displacement);
3520           AstNode *effective_address =  new AstNode(plusOp, base,
3521                                                     disp);
3522           the_args[0] = new AstNode(AstNode::DataIndir, effective_address);
3523           
3524           the_args[1] = new AstNode(AstNode::Constant,
3525                                     (void *) callSite->iPgetAddress());
3526           func = new AstNode("DYNINSTRegisterCallee", the_args);
3527           miniTrampHandle mtHandle;
3528           addInstFunc(&mtHandle, this, callSite, func, callPreInsn,
3529                       orderFirstAtPoint, true, false);
3530         }
3531       }
3532       break;
3533       
3534     default:
3535       cerr << "Unexpected addressing type in MonitorCallSite at addr:" 
3536            << hex << callSite->iPgetAddress() << dec 
3537            << "The daemon declines the monitoring request of this call site." 
3538            << endl; 
3539       break;
3540     }
3541   }
3542   else if(i.isCall()){
3543     //Regular callees are statically determinable, so no need to 
3544     //instrument them
3545     return true;
3546   }
3547   else {
3548     cerr << "Unexpected instruction in MonitorCallSite()!!!\n";
3549   }
3550   return true;
3551 }
3552 #endif
3553
3554 #if (defined(i386_unknown_solaris2_5) || defined(i386_unknown_linux2_0))
3555 #include <sys/signal.h>
3556 //#include <sys/ucontext.h>
3557
3558 void
3559 BaseTrampTrapHandler (int)//, siginfo_t*, ucontext_t*)
3560 {
3561   cout << "In BaseTrampTrapHandler()" << endl;
3562   // unset trap handler, so that DYNINSTtrapHandler can take place
3563   if (sigaction(SIGTRAP, NULL, NULL) != 0) {
3564     perror("sigaction(SIGTRAP)");
3565     assert(0);
3566     abort();
3567   }
3568 }
3569 #endif
3570
3571 bool deleteBaseTramp(process *, instPoint *,
3572                      trampTemplate *, instInstance *lastMT)
3573 {
3574         cerr << "WARNING : deleteBaseTramp is unimplemented "
3575              << "(after the last instrumentation deleted)" << endl;
3576         return false;
3577 }
3578
3579
3580 #ifdef BPATCH_LIBRARY
3581 /*
3582  * createInstructionInstPoint
3583  *
3584  * Create a BPatch_point instrumentation point at the given address, which
3585  * is guaranteed not be one of the "standard" inst points.
3586  *
3587  * proc         The process in which to create the inst point.
3588  * address      The address for which to create the point.
3589  */
3590 BPatch_point *createInstructionInstPoint(process* proc, void *address,
3591                                          BPatch_point** alternative,
3592                                          BPatch_function* bpf)
3593 {
3594     /*
3595      * Get some objects we need, such as the enclosing function, image, etc.
3596      */
3597     pd_Function *func = NULL;
3598     if(bpf)
3599         func = (pd_Function*)bpf->func;
3600     else
3601         func = (pd_Function*)proc->findFuncByAddr((Address)address);
3602
3603     if (func == NULL) // Should make an error callback here?
3604         return NULL;
3605
3606     const image *image = func->file()->exec();
3607
3608     Address imageBase;
3609     proc->getBaseAddress(image, imageBase);
3610     Address relAddr = (Address)address - imageBase;
3611
3612     BPatch_function *bpfunc = proc->findOrCreateBPFunc(func);
3613         
3614     /*
3615      * Check if the address points to the beginning of an instruction.
3616      */
3617     bool isInstructionStart = false;
3618
3619     const unsigned char *ptr =
3620         (const unsigned char *)image->getPtrToInstruction(func->getAddress(0));
3621
3622     instruction insn;
3623     unsigned insnSize;
3624
3625     Address funcEnd = func->getAddress(proc) + func->size();
3626     for (Address checkAddr = func->getAddress(proc);
3627         checkAddr < funcEnd; ptr += insnSize, checkAddr += insnSize) {
3628
3629         if (checkAddr == (Address)address) {
3630             isInstructionStart = true;
3631             break;
3632         } else if (checkAddr > (Address)address) {
3633             break;
3634         }
3635