Removed file name and line number from error message in process::attach().
[dyninst.git] / dyninstAPI / src / solaris.C
1 /*
2  * Copyright (c) 1996 Barton P. Miller
3  * 
4  * We provide the Paradyn Parallel Performance Tools (below
5  * described as Paradyn") on an AS IS basis, and do not warrant its
6  * validity or performance.  We reserve the right to update, modify,
7  * or discontinue this software at any time.  We shall have no
8  * obligation to supply such updates or modifications or any other
9  * form of support to you.
10  * 
11  * This license is for research uses.  For such uses, there is no
12  * charge. We define "research use" to mean you may freely use it
13  * inside your organization for whatever purposes you see fit. But you
14  * may not re-distribute Paradyn or parts of Paradyn, in any form
15  * source or binary (including derivatives), electronic or otherwise,
16  * to any other organization or entity without our permission.
17  * 
18  * (for other uses, please contact us at paradyn@cs.wisc.edu)
19  * 
20  * All warranties, including without limitation, any warranty of
21  * merchantability or fitness for a particular purpose, are hereby
22  * excluded.
23  * 
24  * By your use of Paradyn, you understand and agree that we (or any
25  * other person or entity with proprietary rights in Paradyn) are
26  * under no obligation to provide either maintenance services,
27  * update services, notices of latent defects, or correction of
28  * defects for Paradyn.
29  * 
30  * Even if advised of the possibility of such damages, under no
31  * circumstances shall we (or any other person or entity with
32  * proprietary rights in the software licensed hereunder) be liable
33  * to you or any third party for direct, indirect, or consequential
34  * damages of any character regardless of type of action, including,
35  * without limitation, loss of profits, loss of use, loss of good
36  * will, or computer failure or malfunction.  You agree to indemnify
37  * us (and any other person or entity with proprietary rights in the
38  * software licensed hereunder) for any and all liability it may
39  * incur to third parties resulting from your use of Paradyn.
40  */
41
42 // $Id: solaris.C,v 1.89 2000/03/22 20:32:43 mihai Exp $
43
44 #include "dyninstAPI/src/symtab.h"
45 #include "util/h/headers.h"
46 #include "dyninstAPI/src/os.h"
47 #include "dyninstAPI/src/process.h"
48 #ifndef BPATCH_LIBRARY
49 #include "dyninstAPI/src/pdThread.h"
50 #endif
51 #include "dyninstAPI/src/stats.h"
52 #include "util/h/Types.h"
53 #include <sys/ioctl.h>
54 #include <fcntl.h>
55 #include <sys/termios.h>
56 #include <unistd.h>
57 #include "dyninstAPI/src/showerror.h"
58 #include "util/h/pathName.h" // concat_pathname_components()
59 #include "util/h/debugOstream.h"
60 #include "util/h/solarisKludges.h"
61
62 #if defined (sparc_sun_solaris2_4)
63 #include "dyninstAPI/src/inst-sparc.h"
64 #else
65 #include "dyninstAPI/src/inst-x86.h"
66 #endif
67
68 #include "instPoint.h"
69
70 #include <sys/procfs.h>
71 #include <stropts.h>
72 #include <poll.h>
73 #include <limits.h>
74 #include <link.h>
75 #include <dlfcn.h>
76
77 #define DLOPEN_MODE (RTLD_NOW | RTLD_GLOBAL)
78
79 extern "C" {
80 extern int ioctl(int, int, ...);
81 extern long sysconf(int);
82 };
83
84 // The following were defined in process.C
85 extern debug_ostream attach_cerr;
86 extern debug_ostream inferiorrpc_cerr;
87 extern debug_ostream shmsample_cerr;
88 extern debug_ostream forkexec_cerr;
89 extern debug_ostream metric_cerr;
90 extern debug_ostream signal_cerr;
91
92 /*
93    Define the indices of some registers to be used with pr_reg.
94    These values are different on sparc and x86 platforms.
95    RETVAL_REG: the registers that holds the return value of calls ($o0 on sparc,
96                %eax on x86).
97    PC_REG: program counter
98    FP_REG: frame pointer (%i7 on sparc, %ebp on x86) 
99 */
100 #ifdef sparc_sun_solaris2_4
101 #define PARAM1_REG (R_O0)
102 #define RETVAL_REG (R_O0)
103 #define PC_REG (R_PC)
104 #define FP_REG (R_O6)
105 #endif
106 #ifdef i386_unknown_solaris2_5
107 #define RETVAL_REG (EAX)
108 #define SP_REG (UESP)
109 #define PC_REG (EIP)
110 #define FP_REG (EBP)
111 #endif
112
113
114 extern bool isValidAddress(process *proc, Address where);
115 extern void generateBreakPoint(instruction &insn);
116
117 /*
118    osTraceMe is called after we fork a child process to set
119    a breakpoint on the exit of the exec system call.
120    When /proc is used, this breakpoint **will not** cause a SIGTRAP to 
121    be sent to the process. The parent should use PIOCWSTOP to wait for 
122    the child.
123 */
124 void OS::osTraceMe(void) {
125   sysset_t exitSet;
126   char procName[128];
127
128   sprintf(procName,"/proc/%05d", (int)getpid());
129   int fd = P_open(procName, O_RDWR, 0);
130   if (fd < 0) {
131     fprintf(stderr, "osTraceMe: open failed: %s\n", sys_errlist[errno]); 
132     fflush(stderr);
133     P__exit(-1); // must use _exit here.
134   }
135
136   /* set a breakpoint at the exit of exec/execve */
137   premptyset(&exitSet);
138   praddset(&exitSet, SYS_exec);
139   praddset(&exitSet, SYS_execve);
140
141   if (ioctl(fd, PIOCSEXIT, &exitSet) < 0) {
142     fprintf(stderr, "osTraceMe: PIOCSEXIT failed: %s\n", sys_errlist[errno]); 
143     fflush(stderr);
144     P__exit(-1); // must use _exit here.
145   }
146
147   errno = 0;
148   close(fd);
149   return;
150 }
151
152
153 // already setup on this FD.
154 // disconnect from controlling terminal 
155 void OS::osDisconnect(void) {
156   int ttyfd = open ("/dev/tty", O_RDONLY);
157   ioctl (ttyfd, TIOCNOTTY, NULL); 
158   P_close (ttyfd);
159 }
160
161 bool process::continueWithForwardSignal(int) {
162    if (-1 == ioctl(proc_fd, PIOCRUN, NULL)) {
163       perror("could not forward signal in PIOCRUN");
164       return false;
165    }
166
167    return true;
168 }
169
170 #ifndef BPATCH_LIBRARY
171 bool process::dumpImage() {return false;}
172 #else
173 bool process::dumpImage(string imageFileName) 
174 {
175     int newFd;
176     image *im;
177     string command;
178
179     im = getImage();
180     string origFile = im->file();
181
182
183     // first copy the entire image file
184     command = "cp ";
185     command += origFile;
186     command += " ";
187     command += imageFileName;
188     system(command.string_of());
189
190     // now open the copy
191     newFd = open(imageFileName.string_of(), O_RDWR, 0);
192     if (newFd < 0) {
193         // log error
194         return false;
195     }
196
197     Elf *elfp = elf_begin(newFd, ELF_C_READ, 0);
198     Elf_Scn *scn = 0;
199     Address baseAddr = 0;
200     int length = 0;
201     int offset = 0;
202
203     Elf32_Ehdr* ehdrp;
204     Elf_Scn* shstrscnp  = 0;
205     Elf_Data* shstrdatap = 0;
206     Elf32_Shdr* shdrp;
207
208     assert(ehdrp = elf32_getehdr(elfp));
209     assert(((shstrscnp = elf_getscn(elfp, ehdrp->e_shstrndx)) != 0) &&
210            ((shstrdatap = elf_getdata(shstrscnp, 0)) != 0));
211     const char* shnames = (const char *) shstrdatap->d_buf;
212
213     while ((scn = elf_nextscn(elfp, scn)) != 0) {
214         const char* name;
215
216         shdrp = elf32_getshdr(scn);
217         name = (const char *) &shnames[shdrp->sh_name];
218         if (!strcmp(name, ".text")) {
219             offset = shdrp->sh_offset;
220             length = shdrp->sh_size;
221             baseAddr = shdrp->sh_addr;
222             break;
223         }
224     }
225
226
227     char tempCode[length];
228
229
230     bool ret = readTextSpace_((void *) baseAddr, length, tempCode);
231     if (!ret) {
232        // log error
233        return false;
234     }
235
236     lseek(newFd, offset, SEEK_SET);
237     write(newFd, tempCode, length);
238     close(newFd);
239
240     return true;
241 }
242 #endif
243
244 #ifdef BPATCH_LIBRARY
245 /*
246  * Use by dyninst to set events we care about from procfs
247  *
248  */
249 bool process::setProcfsFlags()
250 {
251
252   long flags = PR_BPTADJ;
253   if (BPatch::bpatch->postForkCallback) {
254       // cause the child to inherit trap-on-exit from exec and other traps
255       // so we can learn of the child (if the user cares)
256       flags = PR_BPTADJ | PR_FORK | PR_ASYNC | PR_RLC;
257   }
258
259   if (ioctl (proc_fd, PIOCSET, &flags) < 0) {
260     fprintf(stderr, "attach: PIOCSET failed: %s\n", sys_errlist[errno]);
261     close(proc_fd);
262     return false;
263   }
264
265   // cause a stop on the exit from fork
266   sysset_t sysset;
267
268   if (ioctl(proc_fd, PIOCGEXIT, &sysset) < 0) {
269     fprintf(stderr, "attach: ioctl failed: %s\n", sys_errlist[errno]);
270     close(proc_fd);
271     return false;
272   }
273
274   if (BPatch::bpatch->postForkCallback) {
275       praddset (&sysset, SYS_fork);
276       praddset (&sysset, SYS_fork1);
277       praddset (&sysset, SYS_exec);
278       praddset (&sysset, SYS_execve);
279   }
280   
281   if (ioctl(proc_fd, PIOCSEXIT, &sysset) < 0) {
282     fprintf(stderr, "attach: ioctl failed: %s\n", sys_errlist[errno]);
283     close(proc_fd);
284     return false;
285   }
286
287   // now worry about entry too
288   if (ioctl(proc_fd, PIOCGENTRY, &sysset) < 0) {
289     fprintf(stderr, "attach: ioctl failed: %s\n", sys_errlist[errno]);
290     close(proc_fd);
291     return false;
292   }
293
294   if (BPatch::bpatch->exitCallback) {
295       praddset (&sysset, SYS_exit);
296   }
297
298   if (BPatch::bpatch->preForkCallback) {
299       praddset (&sysset, SYS_fork);
300       praddset (&sysset, SYS_fork1);
301       praddset (&sysset, SYS_vfork);
302       // praddset (&sysset, SYS_waitsys);
303   }
304
305   // should these be for exec callback??
306   prdelset (&sysset, SYS_exec);
307   prdelset (&sysset, SYS_execve);
308   
309   if (ioctl(proc_fd, PIOCSENTRY, &sysset) < 0) {
310     fprintf(stderr, "attach: ioctl failed: %s\n", sys_errlist[errno]);
311     close(proc_fd);
312     return false;
313   }
314
315   return true;
316 }
317 #endif
318
319 /* 
320    execResult: return the result of an exec system call - true if succesful.
321    The traced processes will stop on exit of an exec system call, just before
322    returning to user code. At this point the return value (errno) is already
323    written to a register, and we need to check if the return value is zero.
324  */
325 static inline bool execResult(prstatus_t stat) {
326   return (stat.pr_reg[RETVAL_REG] == 0);
327 }
328
329 /*
330    wait for inferior processes to terminate or stop.
331 */
332 #ifdef BPATCH_LIBRARY
333 int process::waitProcs(int *status, bool block) {
334 #else
335 int process::waitProcs(int *status) {
336 #endif
337    extern vector<process*> processVec;
338
339    static struct pollfd fds[OPEN_MAX];  // argument for poll
340    static int selected_fds;             // number of selected
341    static int curr;                     // the current element of fds
342
343 #ifdef BPATCH_LIBRARY
344    do {
345 #endif
346
347    /* Each call to poll may return many selected fds. Since we only report the
348       status of one process per call to waitProcs, we keep the result of the
349       last poll buffered, and simply process an element from the buffer until
350       all of the selected fds in the last poll have been processed.
351    */
352
353 #ifdef BPATCH_LIBRARY
354    // force a fresh poll each time, processes may have been added/deleted
355    //   since the last call. - jkh 1/31/00
356    selected_fds = 0;
357 #endif
358
359     if (selected_fds == 0) {
360      // printf("polling for: ");
361      for (unsigned u = 0; u < processVec.size(); u++) {
362        // printf("checking %d\n", processVec[u]->getPid());
363        if (processVec[u] && 
364                 (processVec[u]->status() == running || 
365                  processVec[u]->status() == neonatal)) {
366            // printf("   polling %d\n", processVec[u]->getPid());
367            fds[u].fd = processVec[u]->proc_fd;
368        } else {
369            fds[u].fd = -1;
370        }        
371        fds[u].events = POLLPRI;
372        fds[u].revents = 0;
373      }
374      // printf("\n");
375
376 #ifdef BPATCH_LIBRARY
377      int timeout;
378      if (block) timeout = INFTIM;
379      else timeout = 0;
380      selected_fds = poll(fds, processVec.size(), timeout);
381 #else
382      selected_fds = poll(fds, processVec.size(), 0);
383 #endif
384      if (selected_fds < 0) {
385        fprintf(stderr, "waitProcs: poll failed: %s\n", sys_errlist[errno]);
386        selected_fds = 0;
387        return 0;
388      }
389
390      curr = 0;
391    }
392    
393    if (selected_fds > 0) {
394      while (fds[curr].revents == 0)
395        ++curr;
396
397      // fds[curr] has an event of interest
398      prstatus_t stat;
399      int ret = 0;
400
401 #ifdef PURE_BUILD
402      // explicitly initialize "stat" struct (to pacify Purify)
403      // (at least initialize those components which we actually use)
404      stat.pr_flags = 0x0000;
405      stat.pr_why   = 0;
406      stat.pr_what  = 0;
407      stat.pr_reg[RETVAL_REG] = 0;
408 #endif
409
410 #ifdef BPATCH_LIBRARY
411      if (fds[curr].revents & POLLHUP) {
412          do {
413              ret = waitpid(processVec[curr]->getPid(), status, 0);
414          } while ((ret < 0) && (errno == EINTR));
415          ret = -1;
416          if (ret < 0) {
417              // This means that the application exited, but was not our child
418              // so it didn't wait around for us to get it's return code.  In
419              // this case, we can't know why it exited or what it's return
420              // code was.
421              ret = processVec[curr]->getPid();
422              *status = 0;
423              // is this the bug??
424              // processVec[curr]->continueProc_();
425          }
426          assert(ret == processVec[curr]->getPid());
427      } else
428 #endif
429      if (ioctl(fds[curr].fd, PIOCSTATUS, &stat) != -1 
430          && ((stat.pr_flags & PR_STOPPED) || (stat.pr_flags & PR_ISTOP))) {
431        switch (stat.pr_why) {
432        case PR_SIGNALLED:
433          // return the signal number
434          *status = stat.pr_what << 8 | 0177;
435          ret = processVec[curr]->getPid();
436 #if defined(USES_LIBDYNINSTRT_SO)
437          if (!processVec[curr]->dyninstLibAlreadyLoaded() && 
438              processVec[curr]->wasCreatedViaAttach()) {
439            // make sure we are stopped in the eyes of paradynd - naim
440            bool wasRunning = (processVec[curr]->status() == running);
441            if (processVec[curr]->status() != stopped)
442              processVec[curr]->Stopped();   
443            if(processVec[curr]->isDynamicallyLinked()) {
444              processVec[curr]->handleIfDueToSharedObjectMapping();
445            }
446            if (processVec[curr]->trapDueToDyninstLib()) {
447              // we need to load libdyninstRT.so.1 - naim
448              processVec[curr]->handleIfDueToDyninstLib();
449            }
450            if (wasRunning) 
451              if (!processVec[curr]->continueProc()) assert(0);
452          }
453 #endif
454          break;
455        case PR_SYSEXIT: {
456          // exit of a system call.
457          process *p = processVec[curr];
458
459          if (p->RPCs_waiting_for_syscall_to_complete) {
460             // reset PIOCSEXIT mask
461             // inferiorrpc_cerr << "solaris got PR_SYSEXIT!" << endl;
462             assert(p->save_exitset_ptr != NULL);
463             if (-1 == ioctl(p->proc_fd, PIOCSEXIT, p->save_exitset_ptr))
464                assert(false);
465             /*
466              * according to process.h, p->save_exitset_ptr is
467              * of type ( sysset_t * ) on Solaris
468              */
469             delete [] ( sysset_t * )( p->save_exitset_ptr );
470             p->save_exitset_ptr = NULL;
471
472             // fall through on purpose (so status, ret get set)
473          } else if (((stat.pr_what == SYS_exec) || 
474                      (stat.pr_what == SYS_execve)) && !execResult(stat)) {
475            // a failed exec. continue the process
476            processVec[curr]->continueProc_();
477            break;
478          }          
479
480 #ifdef BPATCH_LIBRARY
481          if ((stat.pr_what == SYS_fork) || 
482              (stat.pr_what == SYS_fork1)) {
483              int childPid = stat.pr_reg[RETVAL_REG];
484              if (childPid == getpid()) {
485                  // this is a special case where the normal createProcess code
486                  // has created this process, but the attach routine runs soon
487                  // enough that the child (of the mutator) gets a fork exit
488                  // event.  We don't care about this event, so we just continue
489                  // the process - jkh 1/31/00
490                  processVec[curr]->continueProc_();
491                  process *theParent = processVec[curr];
492                  theParent->status_ = running;
493                  return (0);
494              } else if (childPid > 0) {
495                  unsigned int i;
496
497                  for (i=0; i < processVec.size(); i++) {
498                      if (processVec[i]->getPid() == childPid) break;
499                  }
500                  if (i== processVec.size()) {
501                      // this is a new child, register it with dyninst
502                      int parentPid = processVec[curr]->getPid();
503                      process *theParent = processVec[curr];
504                      process *theChild = new process(*theParent, (int)childPid, -1);
505                      // the parent loaded it!
506                      theChild->hasLoadedDyninstLib = true;
507
508                      processVec += theChild;
509                      activeProcesses++;
510
511                      // it's really stopped, but we need to mark it running so
512                      //   it can report to us that it is stopped - jkh 1/5/00
513                      // or should this be exited???
514                      theChild->status_ = neonatal;
515
516                      // parent is stopped too (on exit fork event)
517                      theParent->status_ = stopped;
518
519                      theChild->execFilePath = 
520                          theChild->tryToFindExecutable("", childPid);
521                      theChild->inExec = false;
522                      BPatch::bpatch->registerForkedThread(parentPid,
523                          childPid, theChild);
524                  }
525              } else {
526                  printf("fork errno %d\n", stat.pr_reg[RETVAL_REG]);
527              }
528          } else if (((stat.pr_what == SYS_exec) || 
529                      (stat.pr_what == SYS_execve)) && execResult(stat)) {
530              process *proc = processVec[curr];
531              proc->execFilePath = proc->tryToFindExecutable("", proc->getPid());
532
533              // only handle if this is in the child - is this right??? jkh
534              if (proc->reachedFirstBreak) {
535                  // mark this for the sig TRAP that will occur soon
536                  proc->inExec = true;
537
538                  // leave process stopped until signal handler runs
539                  // mark it running so we get the stop signal
540                  proc->status_ = stopped;
541
542                  // reset buffer pool to empty (exec clears old mappings)
543                  vector<heapItem *> emptyHeap;
544                  proc->heap.bufferPool = emptyHeap;
545              }
546          } else {
547              printf("got unexpected PIOCSEXIT\n");
548              printf("  call is return from syscall #%d\n", stat.pr_what);
549          }
550 #endif
551
552          *status = SIGTRAP << 8 | 0177;
553          ret = processVec[curr]->getPid();
554          break;
555        }
556
557 #ifdef BPATCH_LIBRARY
558        case PR_SYSENTRY: {
559          bool alreadyCont = false;
560          process *p = processVec[curr];
561
562          if ((stat.pr_what == SYS_fork) || (stat.pr_what == SYS_vfork) ||
563              (stat.pr_what == SYS_fork1)) {
564              if (BPatch::bpatch->preForkCallback) {
565                  assert(p->thread);
566                  p->setProcfsFlags();
567                  BPatch::bpatch->preForkCallback(p->thread, NULL);
568              }
569
570              if (stat.pr_what == SYS_vfork)  {
571                  unsigned int i;
572                  int childPid = 0;
573                  alreadyCont = true;
574                  struct DYNINST_bootstrapStruct bootRec;
575
576                  (void) processVec[curr]->continueProc_();
577                  processVec[curr]->status_ = stopped;
578                  do {
579                      processVec[curr]->extractBootstrapStruct(&bootRec);
580
581                      childPid = bootRec.pid;
582                  } while (bootRec.event != 3);
583
584                  for (i=0; i < processVec.size(); i++) {
585                      if (processVec[i]->getPid() == childPid) break;
586                  }
587                  if (i== processVec.size()) {
588                      // this is a new child, register it with dyninst
589                      int parentPid = processVec[curr]->getPid();
590                      process *theParent = processVec[curr];
591                      process *theChild = new process(*theParent, (int)childPid, -1);
592                      processVec += theChild;
593                      activeProcesses++;
594
595                      // it's really stopped, but we need to mark it running so
596                      //   it can report to us that it is stopped - jkh 1/5/00
597                      // or should this be exited???
598                      theChild->status_ = running;
599
600                      theChild->execFilePath = 
601                          theChild->tryToFindExecutable("", childPid);
602                      BPatch::bpatch->registerForkedThread(parentPid,
603                          childPid, theChild);
604                  }
605              }
606          } else if (stat.pr_what == SYS_exit) {
607 #ifdef i386_unknown_solaris2_5
608              int code;
609              bool readRet;
610              unsigned long sp;
611              
612              sp = stat.pr_reg[SP_REG];
613              // exit code is at sp+4 when the syscall for exit is invoked
614              readRet = processVec[curr]->readDataSpace_((void *) (sp+4), 
615                  sizeof(int), (caddr_t) &code);
616              if (!readRet) {
617                  char errorLing[256];
618                  sprintf(errorLine, "in readDataSpace, unable to read at %lx\n",
619                      sp+4);
620                  logLine(errorLine);
621              }
622 #else
623              int code = stat.pr_reg[PARAM1_REG];
624 #endif
625              process *proc = processVec[curr];
626
627              proc->status_ = stopped;
628
629              BPatch::bpatch->registerExit(proc->thread, code);
630
631              proc->continueProc();
632              alreadyCont = true;
633
634          } else {
635              printf("got PR_SYSENTRY\n");
636              printf("    unhandeled sys call #%d\n", stat.pr_what);
637          }
638          if (!alreadyCont) (void) processVec[curr]->continueProc_();
639          break;
640        }
641 #endif
642
643        case PR_REQUESTED:
644          assert(0);
645          break;
646        case PR_JOBCONTROL:
647          assert(0);
648          break;
649        }        
650      }
651
652      --selected_fds;
653      ++curr;
654
655      if (ret > 0) {
656        return ret;
657      }
658    }
659
660 #ifdef BPATCH_LIBRARY
661    } while (block);
662    return 0;
663 #else
664    return waitpid(0, status, WNOHANG);
665 #endif
666 }
667
668
669 static char *extract_string_ptr(int procfd, char **ptr) {
670    // we want to return *ptr.
671
672    if (-1 == lseek(procfd, (long)ptr, SEEK_SET))
673       assert(false);
674
675    char *result;
676    if (-1 == read(procfd, &result, sizeof(result)))
677       assert(false);
678
679    return result;   
680 }
681
682 string extract_string(int procfd, const char *inferiorptr) {
683    // assuming inferiorptr points to a null-terminated string in the inferior
684    // process, extract it and return it.
685
686    if (-1 == lseek(procfd, (long)inferiorptr, SEEK_SET))
687       return "";
688
689    string result;
690    while (true) {
691       char buffer[100];
692       if (-1 == read(procfd, &buffer, 80))
693          return "";
694       buffer[80] = '\0';
695       result += buffer;
696
697       // was there a '\0' anywhere in chars 0 thru 79?  If so then
698       // we're done
699       for (unsigned lcv=0; lcv < 80; lcv++)
700          if (buffer[lcv] == '\0') {
701             //attach_cerr << "extract_string returning " << result << endl;
702             return result;
703          }
704    }
705 }
706
707 bool get_ps_stuff(int proc_fd, string &argv0, string &pathenv, string &cwdenv) {
708    // Use ps info to obtain argv[0], PATH, and curr working directory of the
709    // inferior process designated by proc_fd.  Writes to argv0, pathenv, cwdenv.
710
711    prpsinfo the_psinfo;
712 #ifdef PURE_BUILD
713    // explicitly initialize "the_psinfo" struct (to pacify Purify)
714    // (at least initialize those components which we actually use)
715    the_psinfo.pr_zomb = 0;
716    the_psinfo.pr_argc = 0;
717    the_psinfo.pr_argv = NULL;
718    the_psinfo.pr_envp = NULL;
719 #endif
720
721    if (-1 == ioctl(proc_fd, PIOCPSINFO, &the_psinfo))
722        return false;
723
724    if (the_psinfo.pr_zomb)
725        return false;
726
727    // get argv[0].  It's in the_psinfo.pr_argv[0], but that's a ptr in the inferior
728    // space, so we need to /proc read() it out.  Also, the_psinfo.pr_argv is a char **
729    // not a char* so we even need to /proc read() to get a pointer value.  Ick.
730    assert(the_psinfo.pr_argv != NULL);
731    char *ptr_to_argv0 = extract_string_ptr(proc_fd, the_psinfo.pr_argv);
732    argv0 = extract_string(proc_fd, ptr_to_argv0);
733
734    // Get the PWD and PATH environment variables from the application.
735    char **envptr = the_psinfo.pr_envp;
736    while (true) {
737       // dereference envptr; check for NULL
738       char *env = extract_string_ptr(proc_fd, envptr);
739       if (env == NULL)
740          break;
741
742       string env_value = extract_string(proc_fd, env);
743       if (env_value.prefixed_by("PWD=") || env_value.prefixed_by("CWD=")) {
744          cwdenv = env_value.string_of() + 4; // skip past "PWD=" or "CWD="
745          attach_cerr << "get_ps_stuff: using PWD value of: " << cwdenv << endl;
746       }
747       else if (env_value.prefixed_by("PATH=")) {
748          pathenv = env_value.string_of() + 5; // skip past the "PATH="
749          attach_cerr << "get_ps_stuff: using PATH value of: " << pathenv << endl;
750       }
751
752       envptr++;
753    }
754
755    return true;
756 }
757
758
759 /*
760    Open the /proc file correspoding to process pid, 
761    set the signals to be caught to be only SIGSTOP and SIGTRAP,
762    and set the kill-on-last-close and inherit-on-fork flags.
763 */
764 extern string pd_flavor ;
765 bool process::attach() {
766   char procName[128];
767
768   // QUESTION: does this attach operation lead to a SIGTRAP being forwarded
769   // to paradynd in all cases?  How about when we are attaching to an
770   // already-running process?  (Seems that in the latter case, no SIGTRAP
771   // is automatically generated)
772
773   // step 1) /proc open: attach to the inferior process
774   sprintf(procName,"/proc/%05d", (int)pid);
775   int fd = P_open(procName, O_RDWR, 0);
776   if (fd < 0) {
777     fprintf( stderr, "attach: open failed: %s\n", sys_errlist[errno] );
778 //     fprintf(stderr, "attach: open failed: %s -- %s[%d]\n",
779 //          sys_errlist[errno], __FILE__, __LINE__ );
780     return false;
781   }
782
783   // step 2) /proc PIOCSTRACE: define which signals should be forwarded to daemon
784   //   These are (1) SIGSTOP and (2) either SIGTRAP (sparc) or SIGILL (x86), to
785   //   implement inferiorRPC completion detection.
786
787   sigset_t sigs;
788
789   premptyset(&sigs);
790   praddset(&sigs, SIGSTOP);
791
792 #ifndef i386_unknown_solaris2_5
793   praddset(&sigs, SIGTRAP);
794 #endif
795
796 #ifdef i386_unknown_solaris2_5
797   praddset(&sigs, SIGILL);
798 #endif
799
800   if (ioctl(fd, PIOCSTRACE, &sigs) < 0) {
801     fprintf(stderr, "attach: ioctl failed: %s\n", sys_errlist[errno]);
802     close(fd);
803     return false;
804   }
805
806   // Step 3) /proc PIOCSET:
807   // a) turn on the kill-on-last-close flag (kills inferior with SIGKILL when
808   //    the last writable /proc fd closes)
809   // b) turn on inherit-on-fork flag (tracing flags inherited when
810   // child forks) in Paradyn only
811   // c) turn on breakpoint trap pc adjustment (x86 only).
812   // Also, any child of this process will stop at the exit of an exec call.
813
814   proc_fd = fd;
815
816 #ifdef BPATCH_LIBRARY
817   setProcfsFlags();
818
819 // #endif
820 #else
821   //Tempest, do not need to inherit-on-fork
822   long flags ;
823
824   if(process::pdFlavor == string("cow"))
825         flags = PR_KLC |  PR_BPTADJ;
826   else
827         flags = PR_KLC | PR_FORK | PR_BPTADJ;
828   if (ioctl (fd, PIOCSET, &flags) < 0) {
829     fprintf(stderr, "attach: PIOCSET failed: %s\n", sys_errlist[errno]);
830     close(fd);
831     return false;
832   }
833 #endif
834
835   if (!get_ps_stuff(proc_fd, this->argv0, this->pathenv, this->cwdenv))
836       return false;
837
838   return true;
839 }
840
841 #if defined(USES_LIBDYNINSTRT_SO)
842 bool process::trapAtEntryPointOfMain()
843 {
844   prgregset_t regs;
845 #ifdef PURE_BUILD
846   // explicitly initialize "regs" struct (to pacify Purify)
847   // (at least initialize those components which we actually use)
848   for (unsigned r=0; r<(sizeof(regs)/sizeof(regs[0])); r++) regs[r]=0;
849 #endif
850
851   if (ioctl (proc_fd, PIOCGREG, &regs) != -1) {
852     // is the trap instr at main_brk_addr?
853     if(regs[R_PC] == (int)main_brk_addr){ 
854       return(true);
855     }
856   }
857   return(false);
858 }
859
860 bool process::trapDueToDyninstLib()
861 {
862   if (dyninstlib_brk_addr == 0) // not set yet!
863       return(false);
864
865   prgregset_t regs;
866 #ifdef PURE_BUILD
867   // explicitly initialize "regs" struct (to pacify Purify)
868   // (at least initialize those components which we actually use)
869   for (unsigned r=0; r<(sizeof(regs)/sizeof(regs[0])); r++) regs[r]=0;
870 #endif
871
872   if (ioctl (proc_fd, PIOCGREG, &regs) != -1) {
873     // is the trap instr at dyninstlib_brk_addr?
874     if(regs[R_PC] == (int)dyninstlib_brk_addr){ 
875       return(true);
876     }
877   }
878   return(false);
879 }
880
881 void process::handleIfDueToDyninstLib() 
882 {
883   // rewrite original instructions in the text segment we use for 
884   // the inferiorRPC - naim
885   unsigned count = sizeof(savedCodeBuffer);
886   //Address codeBase = getImage()->codeOffset();
887
888   function_base *_startfn = this->findOneFunctionFromAll("_start");
889   Address codeBase = _startfn->getEffectiveAddress(this);
890   assert(codeBase);
891   writeDataSpace((void *)codeBase, count, (char *)savedCodeBuffer);
892
893   // restore registers
894   restoreRegisters(savedRegs); 
895
896 #if defined(i386_unknown_solaris2_5)
897   // restore the stack frame of _start()
898   prgregset_t theIntRegs; theIntRegs = *(prgregset_t *)savedRegs;
899   Address theEBP = theIntRegs[EBP];
900   assert (theEBP);
901   // this is pretty kludge. if the stack frame of _start is not the right
902   // size, this would break.
903   writeDataSpace ((void*)(theEBP-6*sizeof(int)),6*sizeof(int),savedStackFrame);
904 #endif
905
906   delete[] savedRegs;
907   savedRegs = NULL;
908 }
909
910 void process::handleTrapAtEntryPointOfMain()
911 {
912   function_base *f_main = findOneFunction("main");
913   assert(f_main);
914   Address addr = f_main->addr();
915   // restore original instruction 
916 #if defined(sparc_sun_solaris2_4)
917   writeDataSpace((void *)addr, sizeof(instruction), (char *)savedCodeBuffer);
918 #else // x86
919   writeDataSpace((void *)addr, 2, (char *)savedCodeBuffer);
920 #endif
921 }
922
923 void process::insertTrapAtEntryPointOfMain()
924 {
925   function_base *f_main = findOneFunction("main");
926   if (!f_main) {
927     // we can't instrument main - naim
928     showErrorCallback(108,"main() uninstrumentable");
929     extern void cleanUpAndExit(int);
930     cleanUpAndExit(-1); 
931     return;
932   }
933   assert(f_main);
934   Address addr = f_main->addr();
935
936   // save original instruction first
937 #if defined(sparc_sun_solaris2_4)
938   readDataSpace((void *)addr, sizeof(instruction), savedCodeBuffer, true);
939 #else // x86
940   readDataSpace((void *)addr, 2, savedCodeBuffer, true);
941 #endif
942   // and now, insert trap
943   instruction insnTrap;
944   generateBreakPoint(insnTrap);
945 #if defined(sparc_sun_solaris2_4)
946   writeDataSpace((void *)addr, sizeof(instruction), (char *)&insnTrap);  
947 #else //x86. have to use SIGILL instead of SIGTRAP
948   writeDataSpace((void *)addr, 2, insnTrap.ptr());  
949 #endif
950   main_brk_addr = addr;
951 }
952
953 bool process::dlopenDYNINSTlib() {
954   // we will write the following into a buffer and copy it into the
955   // application process's address space
956   // [....LIBRARY's NAME...|code for DLOPEN]
957
958   // write to the application at codeOffset. This won't work if we
959   // attach to a running process.
960   //Address codeBase = this->getImage()->codeOffset();
961   // ...let's try "_start" instead
962   function_base *_startfn = this->findOneFunctionFromAll("_start");
963   Address codeBase = _startfn->getEffectiveAddress(this);
964   assert(codeBase);
965
966   // Or should this be readText... it seems like they are identical
967   // the remaining stuff is thanks to Marcelo's ideas - this is what 
968   // he does in NT. The major change here is that we use AST's to 
969   // generate code for dlopen.
970
971   // savedCodeBuffer[BYTES_TO_SAVE] is declared in process.h
972   readDataSpace((void *)codeBase, sizeof(savedCodeBuffer), savedCodeBuffer, true);
973
974   unsigned char scratchCodeBuffer[BYTES_TO_SAVE];
975   vector<AstNode*> dlopenAstArgs(2);
976
977   Address count = 0;
978
979 #ifdef BPATCH_LIBRARY   /* dyninst API doesn't load libsocket.so.1 */
980   AstNode *dlopenAst;
981 #else
982   dlopenAstArgs[0] = new AstNode(AstNode::Constant, (void*)0); 
983   // library name. We use a scratch value first. We will update this parameter
984   // later, once we determine the offset to find the string - naim
985   dlopenAstArgs[1] = new AstNode(AstNode::Constant, (void*)DLOPEN_MODE); // mode
986   AstNode *dlopenAst = new AstNode("dlopen",dlopenAstArgs);
987   removeAst(dlopenAstArgs[0]);
988   removeAst(dlopenAstArgs[1]);
989 #endif
990
991   // deadList and deadListSize are defined in inst-sparc.C - naim
992   extern Register deadList[];
993   extern unsigned int deadListSize;
994   registerSpace *dlopenRegSpace = new registerSpace(deadListSize/sizeof(Register),
995                                 deadList, (unsigned)0, NULL);
996   dlopenRegSpace->resetSpace();
997
998 #ifndef BPATCH_LIBRARY /* dyninst API doesn't load libsocket.so.1 */
999   dlopenAst->generateCode(this, dlopenRegSpace, (char *)scratchCodeBuffer,
1000                           count, true, true);
1001   writeDataSpace((void *)codeBase, count, (char *)scratchCodeBuffer);
1002 // the following seems to be a redundant relic
1003 //#if defined(sparc_sun_solaris2_4)
1004 //  count += sizeof(instruction);
1005 //#endif
1006 #endif
1007
1008   // we need to make 2 calls to dlopen: one to load libsocket.so.1 and another
1009   // one to load libdyninst.so.1 - naim
1010
1011 #ifndef BPATCH_LIBRARY /* since dyninst API didn't create an ast yet */
1012   removeAst(dlopenAst); // to avoid memory leaks - naim
1013 #endif
1014   dlopenAstArgs[0] = new AstNode(AstNode::Constant, (void*)0);
1015   // library name. We use a scratch value first. We will update this parameter
1016   // later, once we determine the offset to find the string - naim
1017   dlopenAstArgs[1] = new AstNode(AstNode::Constant, (void*)DLOPEN_MODE); // mode
1018   dlopenAst = new AstNode("dlopen",dlopenAstArgs);
1019   removeAst(dlopenAstArgs[0]);
1020   removeAst(dlopenAstArgs[1]);
1021
1022   Address dyninst_count = 0;
1023   dlopenAst->generateCode(this, dlopenRegSpace, (char *)scratchCodeBuffer,
1024                           dyninst_count, true, true);
1025   writeDataSpace((void *)(codeBase+count), dyninst_count, (char *)scratchCodeBuffer);
1026 // the following seems to be a redundant relic
1027 //#if defined(sparc_sun_solaris2_4)
1028 //  dyninst_count += sizeof(instruction);
1029 //#endif
1030   count += dyninst_count;
1031
1032   instruction insnTrap;
1033   generateBreakPoint(insnTrap);
1034 #if defined(sparc_sun_solaris2_4)
1035   writeDataSpace((void *)(codeBase + count), sizeof(instruction), 
1036                  (char *)&insnTrap);
1037   dyninstlib_brk_addr = codeBase + count;
1038   count += sizeof(instruction);
1039 #else //x86
1040   writeDataSpace((void *)(codeBase + count), 2, insnTrap.ptr());
1041   dyninstlib_brk_addr = codeBase + count;
1042   count += 2;
1043 #endif
1044
1045   char libname[256];
1046 #ifdef BPATCH_LIBRARY  /* dyninst API loads a different run-time library */
1047   if (getenv("DYNINSTAPI_RT_LIB") != NULL) {
1048     strcpy((char*)libname,(char*)getenv("DYNINSTAPI_RT_LIB"));
1049     if (access(libname, R_OK)) {
1050          string msg = string(libname) + string(" does not exist or cannot be accessed");
1051          showErrorCallback(101, msg);
1052          return false;
1053     }
1054   } else {
1055     string msg = string("Environment variable DYNINSTAPI_RT_LIB is not defined;"
1056         " should be set to the pathname of the dyninstAPI_RT runtime library.");
1057     showErrorCallback(101, msg);
1058     return false;
1059   }
1060 #else
1061   if (getenv("PARADYN_LIB") != NULL) {
1062     strcpy((char*)libname,(char*)getenv("PARADYN_LIB"));
1063     if (access(libname, R_OK)) {
1064          string msg = string(libname) + string(" does not exist or cannot be accessed");
1065          showErrorCallback(101, msg);
1066          return false;
1067     }
1068   } else {
1069     string msg = string("Environment variable PARADYN_LIB has not been defined"
1070                  " for process") + string(pid);
1071     showErrorCallback(101, msg);
1072     return false;
1073   }
1074 #endif
1075
1076   Address dyninstlib_addr = codeBase + count;
1077
1078   writeDataSpace((void *)(codeBase + count), strlen(libname)+1,
1079                  (caddr_t)libname);
1080   count += strlen(libname)+1;
1081   // we have now written the name of the library after the trap - naim
1082
1083 #ifdef BPATCH_LIBRARY  /* dyninst API doesn't load libsocket.so.1 */
1084   assert(count<=BYTES_TO_SAVE);
1085   // The dyninst API doesn't load the socket library
1086 #else
1087   char socketname[256];
1088   if (getenv("PARADYN_SOCKET_LIB") != NULL) {
1089     strcpy((char*)socketname,(char*)getenv("PARADYN_SOCKET_LIB"));
1090   } else {
1091     strcpy((char*)socketname,(char *)"/usr/lib/libsocket.so.1");
1092   }
1093   Address socketlib_addr = codeBase + count;
1094   writeDataSpace((void *)(codeBase + count), 
1095                  strlen(socketname)+1, (caddr_t)socketname);
1096   count += strlen(socketname)+1;
1097   // we have now written the name of the socket library after the trap - naim
1098   //
1099   assert(count<=BYTES_TO_SAVE);
1100 #endif
1101
1102 #ifdef BPATCH_LIBRARY  /* dyninst API doesn't load libsocket.so.1 */
1103   count = 0; // reset count
1104 #else
1105   // at this time, we know the offset for the library name, so we fix the
1106   // call to dlopen and we just write the code again! This is probably not
1107   // very elegant, but it is easy and it works - naim
1108   // loading the socket library - naim
1109   removeAst(dlopenAst); // to avoid leaking memory
1110   //dlopenAstArgs[0] = new AstNode(AstNode::Constant, (void *)(codeBase+count+strlen(libname)+1));
1111   dlopenAstArgs[0] = new AstNode(AstNode::Constant, (void *)(socketlib_addr));
1112   dlopenAstArgs[1] = new AstNode(AstNode::Constant, (void*)DLOPEN_MODE);
1113   dlopenAst = new AstNode("dlopen",dlopenAstArgs);
1114   removeAst(dlopenAstArgs[0]);
1115   removeAst(dlopenAstArgs[1]);
1116   count = 0; // reset count
1117   dlopenAst->generateCode(this, dlopenRegSpace, (char *)scratchCodeBuffer,
1118                           count, true, true);
1119   writeDataSpace((void *)codeBase, count, (char *)scratchCodeBuffer);
1120   removeAst(dlopenAst);
1121 #endif
1122
1123   // at this time, we know the offset for the library name, so we fix the
1124   // call to dlopen and we just write the code again! This is probably not
1125   // very elegant, but it is easy and it works - naim
1126   removeAst(dlopenAst); // to avoid leaking memory
1127   dlopenAstArgs[0] = new AstNode(AstNode::Constant, (void *)(dyninstlib_addr));
1128   dlopenAstArgs[1] = new AstNode(AstNode::Constant, (void*)DLOPEN_MODE);
1129   dlopenAst = new AstNode("dlopen",dlopenAstArgs);
1130   removeAst(dlopenAstArgs[0]);
1131   removeAst(dlopenAstArgs[1]);
1132   dyninst_count = 0; // reset count
1133   dlopenAst->generateCode(this, dlopenRegSpace, (char *)scratchCodeBuffer,
1134                           dyninst_count, true, true);
1135   writeDataSpace((void *)(codeBase+count), dyninst_count, (char *)scratchCodeBuffer);
1136   removeAst(dlopenAst);
1137   count += dyninst_count;
1138
1139   // save registers
1140   savedRegs = getRegisters();
1141   assert((savedRegs!=NULL) && (savedRegs!=(void *)-1));
1142 #if defined(i386_unknown_solaris2_5)
1143   // save the stack frame of _start()
1144   prgregset_t regs; regs = *(prgregset_t*)savedRegs;
1145   Address theEBP = regs[EBP];
1146   assert (theEBP);
1147   // this is pretty kludge. if the stack frame of _start is not the right
1148   // size, this would break.
1149   readDataSpace((void*)(theEBP-6*sizeof(int)),6*sizeof(int), savedStackFrame, true);
1150 #endif
1151   isLoadingDyninstLib = true;
1152   if (!changePC(codeBase,savedRegs)) // this uses the info in "savedRegs"
1153   {
1154     logLine("WARNING: changePC failed in dlopenDYNINSTlib\n");
1155     assert(0);
1156   }
1157
1158   return true;
1159 }
1160
1161 Address process::get_dlopen_addr() const {
1162   if (dyn != NULL)
1163     return(dyn->get_dlopen_addr());
1164   else 
1165     return(0);
1166 }
1167 #endif
1168
1169 bool process::isRunning_() const {
1170    // determine if a process is running by doing low-level system checks, as
1171    // opposed to checking the 'status_' member vrble.  May assume that attach()
1172    // has run, but can't assume anything else.
1173    prstatus theStatus;
1174 #ifdef PURE_BUILD
1175    // explicitly initialize "theStatus" struct (to pacify Purify)
1176    memset(&theStatus, '\0', sizeof(prstatus));
1177 #endif
1178    if (ioctl(proc_fd, PIOCSTATUS, &theStatus) == -1) {
1179       perror("process::isRunning_()");
1180       assert(false);
1181    }
1182
1183    if (theStatus.pr_flags & PR_STOPPED)
1184       return false;
1185    else
1186       return true;
1187 }
1188
1189 bool process::attach_() {assert(false); return(false);}
1190 bool process::stop_() {assert(false); return(false);}
1191
1192 /* 
1193    continue a process that is stopped 
1194 */
1195 bool process::continueProc_() {
1196   ptraceOps++; ptraceOtherOps++;
1197   prrun_t flags;
1198   prstatus_t stat;
1199   Address pc;  // PC at which we are trying to continue
1200
1201 #ifdef PURE_BUILD
1202   // explicitly initialize "flags" struct (to pacify Purify)
1203   memset(&flags, '\0', sizeof(flags));
1204   // explicitly initialize "stat" struct (to pacify Purify)
1205   // (at least initialize those components which we actually use)
1206   stat.pr_flags = 0x0000;
1207   stat.pr_why   = 0;
1208   stat.pr_what  = 0;
1209 #endif
1210
1211   // a process that receives a stop signal stops twice. We need to run the process
1212   // and wait for the second stop. (The first run simply absorbs the stop signal;
1213   // the second one does the actual continue.)
1214   if (ioctl(proc_fd, PIOCSTATUS, &stat) == -1) return false;
1215
1216   if ((0==stat.pr_flags & PR_STOPPED) && (0==stat.pr_flags & PR_ISTOP))
1217     return false;
1218
1219   if ((stat.pr_flags & PR_STOPPED)
1220       && (stat.pr_why == PR_SIGNALLED)
1221       && (stat.pr_what == SIGSTOP || stat.pr_what == SIGINT)) {
1222     flags.pr_flags = PRSTOP;
1223     if (ioctl(proc_fd, PIOCRUN, &flags) == -1) {
1224       fprintf(stderr, "continueProc_: PIOCRUN failed: %s\n", sys_errlist[errno]);
1225       return false;
1226     }
1227     if (ioctl(proc_fd, PIOCWSTOP, 0) == -1) {
1228       fprintf(stderr, "continueProc_: PIOCWSTOP failed: %s\n", sys_errlist[errno]);
1229       return false;
1230     }
1231   }
1232   flags.pr_flags = PRCSIG; // clear current signal
1233   if (hasNewPC) {
1234     // set new program counter
1235     //cerr << "continueProc_ doing new currentPC: " << (void*)currentPC_ << endl;
1236     flags.pr_vaddr = (caddr_t) currentPC_;
1237     flags.pr_flags |= PRSVADDR;
1238     hasNewPC = false;
1239     pc = currentPC_;
1240   } else
1241     pc = (Address)stat.pr_reg[PC_REG];
1242   
1243   if (! (stoppedInSyscall && pc == postsyscallpc)) {
1244        // Continue the process
1245        if (ioctl(proc_fd, PIOCRUN, &flags) == -1) {
1246            sprintf(errorLine,
1247                    "continueProc_: PIOCRUN 2 failed: %s\n",
1248                    sys_errlist[errno]);
1249            logLine(errorLine);
1250            return false;
1251        }
1252   } else {
1253        // We interrupted a sleeping system call at some previous pause
1254        // (i.e. stoppedInSyscall is true), we have not restarted that
1255        // system call yet, and the current PC is the insn following
1256        // the interrupted call.  It is time to restart the system
1257        // call.
1258        
1259        // Note that when we make the process runnable, we ignore
1260        // `flags', set if `hasNewPC' was true in the previous block,
1261        // because we don't want its PC; we want the PC of the system
1262        // call trap, which was saved in `syscallreg'.
1263        
1264        sysset_t scentry, scsavedentry;
1265        prrun_t run;
1266  
1267        // Restore the registers
1268        if (0 > ioctl(proc_fd, PIOCSREG, syscallreg)) {
1269            sprintf(errorLine,
1270                    "Can't restart sleeping syscall (PIOCSREG)\n");
1271            logLine(errorLine);
1272            return false;
1273        }
1274        
1275        // Save current syscall entry traps
1276        if (0 > ioctl(proc_fd, PIOCGENTRY, &scsavedentry)) {
1277            sprintf(errorLine,
1278                    "warn: Can't restart sleeping syscall (PIOCGENTRY)\n");
1279            logLine(errorLine);
1280            return false;
1281        }
1282        
1283        // Set the process to trap on entry to previously stopped syscall
1284        premptyset(&scentry);
1285        praddset(&scentry, stoppedSyscall);
1286        if (0 > ioctl(proc_fd, PIOCSENTRY, &scentry)) {
1287            sprintf(errorLine,
1288                    "warn: Can't restart sleeping syscall (PIOCSENTRY)\n");
1289            logLine(errorLine);
1290            return false;
1291        }
1292        
1293        // Continue the process
1294        run.pr_flags = PRCSIG; // Clear current signal
1295        if (0 > ioctl(proc_fd, PIOCRUN, &run)) {
1296            sprintf(errorLine,
1297                    "warn: Can't restart sleeping syscall (PIOCRUN)\n");
1298            logLine(errorLine);
1299            return false;
1300        }
1301        
1302        // Wait for the process to stop
1303        if (0 > ioctl(proc_fd, PIOCWSTOP, &stat)) {
1304            sprintf(errorLine,
1305                    "warn: Can't restart sleeping syscall (PIOCWSTOP)\n");
1306            logLine(errorLine);
1307            return false;
1308        }
1309        
1310        // Verify we've stopped at the entry of the call we're trying
1311        // to restart
1312        if (stat.pr_why != PR_SYSENTRY
1313            || stat.pr_what != stoppedSyscall) {
1314            sprintf(errorLine,
1315                    "warn: Can't restart sleeping syscall (verify)\n");
1316            logLine(errorLine);
1317            return false;
1318        }
1319        
1320        // Restore the syscall entry traps
1321        if (0 > ioctl(proc_fd, PIOCSENTRY, &scsavedentry)) {
1322            sprintf(errorLine,
1323                    "warn: Can't restart sleeping syscall (PIOCSENTRY)\n");
1324            logLine(errorLine);
1325            return false;
1326        }
1327        
1328 #if 0
1329        // Restore the registers again.
1330        // Sun told us to do this, but we don't know why.  On the
1331        // SPARC, it doesn't matter -- the system call can be restarted
1332        // whether or not we do this.  On the x86, the restart FAILS if
1333        // we do this.  So Sun can go sit and spin for all I care.
1334        if (0 > ioctl(proc_fd, PIOCSREG, syscallreg)) {
1335            sprintf(errorLine,
1336                    "Can't restart sleeping syscall (PIOCSREG)\n");
1337            logLine(errorLine);
1338            return false;
1339        }
1340 #endif
1341        
1342        // We are done -- the process is in the kernel for the system
1343        // call, with the right registers values.  Make the process
1344        // runnable, restoring its previously blocked signals.
1345        stoppedInSyscall = false;
1346        run.pr_sighold = sighold;
1347        run.pr_flags = PRSHOLD;
1348        if (0 > ioctl(proc_fd, PIOCRUN, &run)) {
1349            sprintf(errorLine,
1350                    "Can't restart sleeping syscall (PIOCRUN)\n");
1351            logLine(errorLine);
1352            return false;
1353        }
1354   }
1355   return true;
1356 }
1357
1358 #ifdef BPATCH_LIBRARY
1359 /*
1360    terminate execution of a process
1361  */
1362 bool process::terminateProc_()
1363 {
1364     long flags = PR_KLC;
1365     if (ioctl (proc_fd, PIOCSET, &flags) < 0)
1366         return false;
1367
1368     Exited();
1369
1370     return true;
1371 }
1372 #endif
1373
1374 #if defined(USES_DYNAMIC_INF_HEAP)
1375 static const Address lowest_addr = 0x0;
1376 void inferiorMallocConstraints(Address near, Address &lo, Address &hi)
1377 {
1378   lo = region_lo(near);
1379   hi = region_hi(near);
1380 }
1381
1382 void inferiorMallocAlign(unsigned &size)
1383 {
1384      /* 32 byte alignment.  Should it be 64? */
1385   size = (size + 0x1f) & ~0x1f;
1386 }
1387 #endif
1388
1389 // We stopped a process that it is a system call.  We abort the
1390 // system call, so that the process can execute an inferior RPC.  We
1391 // save the process state as it was at the ENTRY of the system call,
1392 // so that the system call can be restarted when we continue the
1393 // process.  Note: this code does not deal with multiple LWPs.
1394
1395 int process::abortSyscall()
1396 {
1397   prrun_t run;
1398   sysset_t scexit, scsavedexit;
1399   sysset_t scentry, scsavedentry;
1400   prstatus_t prstatus;
1401
1402   // We do not expect to recursively interrupt system calls.  We could
1403   // probably handle it by keeping a stack of system call state.  But
1404   // we haven't yet seen any reason to have this functionality.
1405   assert(!stoppedInSyscall);
1406   stoppedInSyscall = true;
1407
1408   if (ioctl(proc_fd, PIOCSTATUS, &prstatus) == -1) {
1409       sprintf(errorLine,
1410               "warn : process::pause_ use ioctl to send PICOSTOP returns error : errno = %i\n", errno);
1411       perror("warn : process::abortSyscall ioctl PICOSTOP: ");
1412       logLine(errorLine);
1413   }
1414
1415   // 1. Save the syscall number, registers, and blocked signals
1416   stoppedSyscall = prstatus.pr_syscall;
1417   memcpy(syscallreg, prstatus.pr_reg, sizeof(prstatus.pr_reg));
1418   sighold = prstatus.pr_sighold;
1419 #ifdef i386_unknown_solaris2_5
1420   // From Roger A. Faulkner at Sun (email unknown), 6/29/1997:
1421   //
1422   // On Intel and PowerPC machines, the system call trap instruction
1423   // leaves the PC (program counter, instruction pointer) referring to
1424   // the instruction that follows the system call trap instruction.
1425   // On Sparc machines, the system call trap instruction leaves %pc
1426   // referring to the system call trap instruction itself (the
1427   // operating system increments %pc on exit from the system call).
1428   //
1429   // We have to reset the PC back to the system call trap instruction
1430   // on Intel and PowerPC machines.
1431   //
1432   // This is 7 on Intel, 4 on PowerPC.
1433
1434   // Note: On x86/Linux this should probably be 2 bytes, because Linux
1435   // uses "int" to trap, not lcall.
1436
1437   syscallreg[PC_REG] -= 7;
1438 #endif
1439
1440   // 2. Abort the system call
1441
1442   // Save current syscall exit traps
1443   if (0 > ioctl(proc_fd, PIOCGEXIT, &scsavedexit)) {
1444        sprintf(errorLine,
1445                "warn: Can't get status (PIOCGEXIT) of paused process\n");
1446        logLine(errorLine);
1447        return 0;
1448   }
1449
1450   if (0 > ioctl(proc_fd, PIOCGENTRY, &scsavedentry)) {
1451        sprintf(errorLine,
1452                "warn: Can't get status (PIOCGEXIT) of paused process\n");
1453        logLine(errorLine);
1454        return 0;
1455   }
1456
1457   // Set process to trap on exit from this system call
1458   premptyset(&scexit);
1459   praddset(&scexit, stoppedSyscall);
1460   if (0 > ioctl(proc_fd, PIOCSEXIT, &scexit)) {
1461        sprintf(errorLine,
1462                "warn: Can't step paused process out of syscall (PIOCSEXIT)\n");
1463        logLine(errorLine);
1464        return 0;
1465   }
1466
1467   premptyset(&scentry);
1468   if (0 > ioctl(proc_fd, PIOCSENTRY, &scentry)) {
1469        sprintf(errorLine,
1470                "warn: Can't step paused process out of syscall (PIOCSENTRY)\n");
1471        logLine(errorLine);
1472        return 0;
1473   }
1474
1475   // Continue, aborting this system call and blocking all sigs except
1476   // those needed by DynInst.
1477   sigfillset(&run.pr_sighold);
1478   sigdelset(&run.pr_sighold, SIGTRAP);
1479   sigdelset(&run.pr_sighold, SIGILL);
1480   run.pr_flags = PRSABORT|PRSHOLD;
1481   if (0 > ioctl(proc_fd, PIOCRUN, &run)) {
1482        sprintf(errorLine,
1483                "warn: Can't step paused process out of syscall (PIOCRUN)\n");
1484        logLine(errorLine);
1485        return 0;
1486   }
1487
1488
1489   // Wait for it to stop (at exit of aborted syscall)
1490   if (0 > ioctl(proc_fd, PIOCWSTOP, &prstatus)) {
1491        sprintf(errorLine,
1492                "warn: Can't step paused process out of syscall (PIOCWSTOP)\n");
1493        logLine(errorLine);
1494        return 0;
1495   }
1496
1497   // Note: We assume that is always safe to restart the call after
1498   // aborting it.  We are wrong if it turns out that some
1499   // interruptible system call can make partial progress before we
1500   // abort it.
1501   // We think this is impossible because the proc manpage says EINTR
1502   // would be returned to the process if we didn't trap the syscall
1503   // exit, and the manpages for interruptible system calls say an
1504   // EINTR return value means no progress was made.
1505   // If we are wrong, this is probably the place to decide whether
1506   // and/or how the syscall should be restarted later.
1507
1508   // Verify that we're stopped in the right place
1509   if (((prstatus.pr_flags & (PR_STOPPED|PR_ISTOP))
1510        != (PR_STOPPED|PR_ISTOP))
1511       || prstatus.pr_why != PR_SYSEXIT
1512       || prstatus.pr_syscall != stoppedSyscall) {
1513        sprintf(errorLine,
1514                "warn: Can't step paused process out of syscall (Verify)\n");
1515        logLine(errorLine);
1516        return 0;
1517   }
1518
1519   // Reset the syscall exit traps
1520   if (0 > ioctl(proc_fd, PIOCSEXIT, &scsavedexit)) {
1521        sprintf(errorLine,
1522                "warn: Can't step paused process out of syscall (PIOCSEXIT)\n");
1523        logLine(errorLine);
1524        return 0;
1525   }
1526
1527   // Reset the syscall entry traps
1528   if (0 > ioctl(proc_fd, PIOCSENTRY, &scsavedentry)) {
1529        sprintf(errorLine,
1530                "warn: Can't step paused process out of syscall (PIOCSENTRY)\n");
1531        logLine(errorLine);
1532        return 0;
1533   }
1534
1535   // Remember the current PC.  When we continue the process at this PC
1536   // we will restart the system call.
1537   postsyscallpc = (Address) prstatus.pr_reg[PC_REG];
1538
1539   return 1;
1540 }
1541
1542 /*
1543    pause a process that is running
1544 */
1545 bool process::pause_() {
1546   ptraceOps++; ptraceOtherOps++;
1547   int ioctl_ret;
1548   prstatus_t prstatus;
1549
1550   // /proc PIOCSTOP: direct all LWPs to stop, _and_ wait for them to stop.
1551   ioctl_ret = ioctl(proc_fd, PIOCSTOP, &prstatus);
1552   if (ioctl_ret == -1) {
1553       // see if the reason it failed is that we were already stopped
1554       if (ioctl(proc_fd, PIOCSTATUS, &prstatus) == -1) {
1555           sprintf(errorLine,
1556                   "warn : process::pause_ use ioctl to send PICOSTOP returns error : errno = %i\n", errno);
1557           perror("warn : process::pause_ ioctl PICOSTOP: ");
1558           logLine(errorLine);
1559           return 0;
1560       } else if (!(prstatus.pr_flags & PR_STOPPED)) {
1561           return 0;
1562       }
1563   }
1564
1565 #ifndef MT_THREAD
1566   // Determine if the process was in a system call when we stopped it.
1567   if (! (prstatus.pr_why == PR_REQUESTED
1568          && prstatus.pr_syscall != 0
1569          && (prstatus.pr_flags & PR_ASLEEP))) {
1570        // The process was not in a system call.  We're done.
1571        if (prstatus.pr_why != PR_SYSENTRY) 
1572            return 1;
1573   }
1574
1575   return (abortSyscall());
1576 #endif
1577   return 1;
1578 }
1579
1580 /*
1581    close the file descriptor for the file associated with a process
1582 */
1583 bool process::detach_() {
1584   close(proc_fd);
1585   return true;
1586 }
1587
1588 #ifdef BPATCH_LIBRARY
1589 /*
1590    detach from thr process, continuing its execution if the parameter "cont"
1591    is true.
1592  */
1593 bool process::API_detach_(const bool cont)
1594 {
1595   // Remove the breakpoint that we put in to detect loading and unloading of
1596   // shared libraries.
1597   // XXX We might want to move this into some general cleanup routine for the
1598   //     dynamic_linking object.
1599   if (dyn) {
1600       dyn->unset_r_brk_point(this);
1601   }
1602
1603   // Reset the kill-on-close flag, and the run-on-last-close flag if necessary
1604   long flags = PR_KLC;
1605   if (!cont) flags |= PR_RLC;
1606   if (ioctl (proc_fd, PIOCRESET, &flags) < 0) {
1607     fprintf(stderr, "detach: PIOCRESET failed: %s\n", sys_errlist[errno]);
1608     close(proc_fd);
1609     return false;
1610   }
1611   // Set the run-on-last-close-flag if necessary
1612   if (cont) {
1613     flags = PR_RLC;
1614     if (ioctl (proc_fd, PIOCSET, &flags) < 0) {
1615       fprintf(stderr, "detach: PIOCSET failed: %s\n", sys_errlist[errno]);
1616       close(proc_fd);
1617       return false;
1618     }
1619   }
1620
1621   sigset_t sigs;
1622   premptyset(&sigs);
1623   if (ioctl(proc_fd, PIOCSTRACE, &sigs) < 0) {
1624     fprintf(stderr, "detach: PIOCSTRACE failed: %s\n", sys_errlist[errno]);
1625     close(proc_fd);
1626     return false;
1627   }
1628   if (ioctl(proc_fd, PIOCSHOLD, &sigs) < 0) {
1629     fprintf(stderr, "detach: PIOCSHOLD failed: %s\n", sys_errlist[errno]);
1630     close(proc_fd);
1631     return false;
1632   }
1633
1634   fltset_t faults;
1635   premptyset(&faults);
1636   if (ioctl(proc_fd, PIOCSFAULT, &faults) < 0) {
1637     fprintf(stderr, "detach: PIOCSFAULT failed: %s\n", sys_errlist[errno]);
1638     close(proc_fd);
1639     return false;
1640   }
1641   
1642   sysset_t syscalls;
1643   premptyset(&syscalls);
1644   if (ioctl(proc_fd, PIOCSENTRY, &syscalls) < 0) {
1645     fprintf(stderr, "detach: PIOCSENTRY failed: %s\n", sys_errlist[errno]);
1646     close(proc_fd);
1647     return false;
1648   }
1649   if (ioctl(proc_fd, PIOCSEXIT, &syscalls) < 0) {
1650     fprintf(stderr, "detach: PIOCSEXIT failed: %s\n", sys_errlist[errno]);
1651     close(proc_fd);
1652     return false;
1653   }
1654
1655   close(proc_fd);
1656   return true;
1657 }
1658 #endif
1659
1660 bool process::dumpCore_(const string coreName) 
1661 {
1662   char command[100];
1663
1664   sprintf(command, "gcore %d 2> /dev/null; mv core.%d %s", getPid(), getPid(), 
1665         coreName.string_of());
1666
1667   detach_();
1668   system(command);
1669   attach();
1670
1671   return false;
1672 }
1673
1674 bool process::writeTextWord_(caddr_t inTraced, int data) {
1675 //  cerr << "writeTextWord @ " << (void *)inTraced << endl; cerr.flush();
1676   return writeDataSpace_(inTraced, sizeof(int), (caddr_t) &data);
1677 }
1678
1679 bool process::writeTextSpace_(void *inTraced, u_int amount, const void *inSelf) {
1680 //  cerr << "writeTextSpace pid=" << getPid() << ", @ " << (void *)inTraced << " len=" << amount << endl; cerr.flush();
1681   return writeDataSpace_(inTraced, amount, inSelf);
1682 }
1683
1684 #ifdef BPATCH_SET_MUTATIONS_ACTIVE
1685 bool process::readTextSpace_(void *inTraced, u_int amount, const void *inSelf) {
1686   return readDataSpace_(inTraced, amount, const_cast<void *>(inSelf));
1687 }
1688 #endif
1689
1690 bool process::writeDataSpace_(void *inTraced, u_int amount, const void *inSelf) {
1691   ptraceOps++; ptraceBytes += amount;
1692
1693 //  cerr << "process::writeDataSpace_ pid " << getPid() << " writing " << amount << " bytes at loc " << inTraced << endl;
1694
1695   if (lseek(proc_fd, (off_t)inTraced, SEEK_SET) != (off_t)inTraced) {
1696     perror("lseek");
1697     return false;
1698   }
1699   int written = write(proc_fd, inSelf, amount);
1700   if ((unsigned) written != amount) {
1701       printf("write returned %d\n", written);
1702       printf("attempt to write at %lx\n", (off_t)inTraced);
1703       perror("write");
1704       return false;
1705   } else {
1706       return true;
1707   }
1708 }
1709
1710 bool process::readDataSpace_(const void *inTraced, u_int amount, void *inSelf) {
1711   ptraceOps++; ptraceBytes += amount;
1712   if((lseek(proc_fd, (off_t)inTraced, SEEK_SET)) != (off_t)inTraced) {
1713     printf("error in lseek addr = 0x%lx amount = %d\n",
1714                 (Address)inTraced,amount);
1715     return false;
1716   }
1717   return (read(proc_fd, inSelf, amount) == (int)amount);
1718 }
1719
1720 bool process::loopUntilStopped() {
1721   assert(0);
1722   return(false);
1723 }
1724
1725 #ifdef notdef
1726 // TODO -- only call getrusage once per round
1727 static struct rusage *get_usage_data() {
1728   return NULL;
1729 }
1730 #endif
1731
1732 #ifndef BPATCH_LIBRARY
1733
1734 float OS::compute_rusage_cpu() {
1735   return 0;
1736 }
1737
1738 float OS::compute_rusage_sys() {
1739   return 0;
1740 }
1741
1742 float OS::compute_rusage_min() {
1743   return 0;
1744 }
1745 float OS::compute_rusage_maj() {
1746   return 0;
1747 }
1748
1749 float OS::compute_rusage_swap() {
1750   return 0;
1751 }
1752 float OS::compute_rusage_io_in() {
1753   return 0;
1754 }
1755 float OS::compute_rusage_io_out() {
1756   return 0;
1757 }
1758 float OS::compute_rusage_msg_send() {
1759   return 0;
1760 }
1761 float OS::compute_rusage_msg_recv() {
1762   return 0;
1763 }
1764 float OS::compute_rusage_sigs() {
1765   return 0;
1766 }
1767 float OS::compute_rusage_vol_cs() {
1768   return 0;
1769 }
1770 float OS::compute_rusage_inv_cs() {
1771   return 0;
1772 }
1773
1774 #endif
1775
1776 int getNumberOfCPUs()
1777 {
1778   // _SC_NPROCESSORS_CONF is the number of processors configured in the
1779   // system and _SC_NPROCESSORS_ONLN is the number of those processors that
1780   // are online.
1781   int numberOfCPUs;
1782   numberOfCPUs = (int) sysconf(_SC_NPROCESSORS_ONLN);
1783   if (numberOfCPUs) 
1784     return(numberOfCPUs);
1785   else 
1786     return(1);
1787 }  
1788
1789 // getActiveFrame(): populate Frame object using toplevel frame
1790 void Frame::getActiveFrame(process *p)
1791 {
1792   prstatus_t status;
1793 #ifdef PURE_BUILD
1794   memset(&status, 0, sizeof(prstatus_t));
1795 #endif
1796
1797   int proc_fd = p->getProcFileDescriptor();
1798   if (ioctl(proc_fd, PIOCSTATUS, &status) != -1) {
1799 #if defined(MT_THREAD)
1800       lwp_id_ = status.pr_who;
1801 #endif
1802       fp_ = status.pr_reg[FP_REG];
1803       pc_ = status.pr_reg[PC_REG];
1804   }
1805 }
1806
1807 #if defined(MT_THREAD)
1808 // It is the caller's responsibility to do a "delete [] (*IDs)"
1809 bool process::getLWPIDs(int** IDs) {
1810    int nlwp;
1811    prstatus_t the_psinfo;
1812    if (-1 !=  ioctl(proc_fd, PIOCSTATUS, &the_psinfo)) {
1813      nlwp =  the_psinfo.pr_nlwp ;
1814      id_t *id_p = new id_t [nlwp+1] ;
1815      if (-1 != ioctl(proc_fd, PIOCLWPIDS, id_p)) {
1816        *IDs = new int [nlwp+1];
1817        unsigned i=0; 
1818        do { 
1819          (*IDs)[i] = (int) id_p[i]; 
1820        } while (id_p[i++]);
1821        delete [] id_p;
1822        return true ;
1823      }
1824    }
1825    return false ;
1826 }
1827
1828 bool process::getLWPFrame(int lwp_id, Address* fp, Address *pc) {
1829   prgregset_t regs ;
1830   int lwp_fd = ioctl(proc_fd, PIOCOPENLWP, &(lwp_id));
1831   if (-1 == lwp_fd) {
1832     cerr << "process::getLWPFrame, cannot get lwp_fd" << endl ;
1833     return false ;
1834   }
1835   if (-1 != ioctl(lwp_fd, PIOCGREG, &regs)) {
1836     *fp = regs[FP_REG];
1837     *pc = regs[PC_REG];
1838     close(lwp_fd);
1839     return true ;
1840   }
1841   close(lwp_fd);
1842   return false ;
1843 }
1844
1845 Frame::Frame(pdThread* thr) {
1846   typedef struct {
1847     long    sp;
1848     long    pc;
1849     long    l1; //fsr
1850     long    l2; //fpu_en;
1851     long    l3; //g2, g3, g4
1852     long    l4; 
1853     long    l5; 
1854   } resumestate_t;
1855
1856   fp_ = pc_ = 0 ;
1857   uppermost_ = true ;
1858   lwp_id_ = 0 ;
1859   thread_ = thr ;
1860
1861   process* proc = thr->get_proc();
1862   resumestate_t rs ;
1863   if (thr->get_start_pc() &&
1864       proc->readDataSpace((caddr_t) thr->get_resumestate_p(),
1865                     sizeof(resumestate_t), (caddr_t) &rs, false)) {
1866     fp_ = rs.sp;
1867     pc_ = rs.pc;
1868   } 
1869 }
1870 #endif
1871
1872 #ifdef sparc_sun_solaris2_4
1873
1874 Frame Frame::getCallerFrameNormal(process *p) const
1875 {
1876   prgregset_t regs;
1877 #ifdef PURE_BUILD
1878   // explicitly initialize "regs" struct (to pacify Purify)
1879   // (at least initialize those components which we actually use)
1880   for (unsigned r=0; r<(sizeof(regs)/sizeof(regs[0])); r++) regs[r]=0;
1881 #endif
1882
1883   if (uppermost_) {
1884     function_base *func = p->findFunctionIn(pc_);
1885     if (func) {
1886       if (func->hasNoStackFrame()) { // formerly "isLeafFunc()"
1887         int proc_fd = p->getProcFileDescriptor();
1888         if (ioctl(proc_fd, PIOCGREG, &regs) != -1) {
1889           Frame ret;
1890           ret.pc_ = regs[R_O7] + 8;
1891           ret.fp_ = fp_; // frame pointer unchanged
1892           return ret;
1893         }    
1894       }
1895     }
1896   }
1897   
1898   //
1899   // For the sparc, register %i7 is the return address - 8 and the fp is
1900   // register %i6. These registers can be located in %fp+14*5 and
1901   // %fp+14*4 respectively, but to avoid two calls to readDataSpace,
1902   // we bring both together (i.e. 8 bytes of memory starting at %fp+14*4
1903   // or %fp+56).
1904   // These values are copied to the stack when the application is paused,
1905   // so we are assuming that the application is paused at this point
1906
1907   struct {
1908     Address fp;
1909     Address rtn;
1910   } addrs;
1911   
1912   if (p->readDataSpace((caddr_t)(fp_ + 56), 2*sizeof(int),
1913                        (caddr_t)&addrs, true))
1914   {
1915     Frame ret;
1916     ret.fp_ = addrs.fp;
1917     ret.pc_ = addrs.rtn + 8;
1918     return ret;
1919   }
1920   
1921   return Frame(); // zero frame
1922 }
1923
1924 #if defined(MT_THREAD)
1925 Frame Frame::getCallerFrameThread(process *p) const
1926 {
1927   Frame ret; // zero frame
1928   ret.lwp_id_ = 0;
1929   ret.thread_ = thread_;
1930
1931   // TODO: special handling for uppermost/leaf frame?
1932   /*
1933   prgregset_t regs;
1934 #ifdef PURE_BUILD
1935   // explicitly initialize "regs" struct (to pacify Purify)
1936   // (at least initialize those components which we actually use)
1937   for (unsigned r=0; r<(sizeof(regs)/sizeof(regs[0])); r++) regs[r]=0;
1938 #endif
1939
1940   if (uppermost_) {
1941       func = this->findFunctionIn(pc_);
1942       if (func) {
1943          if (func->hasNoStackFrame()) { // formerly "isLeafFunc()"
1944            int proc_fd = p->getProcFileDescriptor();
1945            if (ioctl(proc_fd, PIOCGREG, &regs) != -1) {
1946              ret.pc_ = regs[R_O7] + 8;
1947              return ret;
1948            }    
1949          }
1950       }
1951   }
1952   */
1953
1954   //
1955   // For the sparc, register %i7 is the return address - 8 and the fp is
1956   // register %i6. These registers can be located in %fp+14*5 and
1957   // %fp+14*4 respectively, but to avoid two calls to readDataSpace,
1958   // we bring both together (i.e. 8 bytes of memory starting at %fp+14*4
1959   // or %fp+56).
1960   // These values are copied to the stack when the application is paused,
1961   // so we are assuming that the application is paused at this point
1962
1963   struct {
1964     Address fp;
1965     Address rtn;
1966   } addrs;
1967
1968   if (p->readDataSpace((caddr_t)(fp_ + 56), sizeof(int)*2, 
1969                        (caddr_t)&addrs, false)) 
1970   {
1971     ret.fp_ = addrs.fp;
1972     ret.pc_ = addrs.rtn + 8;
1973   }
1974
1975   return ret;
1976 }
1977
1978 Frame Frame::getCallerFrameLWP(process *p) const
1979 {
1980   Frame ret; // zero frame
1981   ret.lwp_id_ = lwp_id_;
1982   ret.thread_ = NULL ;
1983
1984   prgregset_t regs;
1985 #ifdef PURE_BUILD
1986   // explicitly initialize "regs" struct (to pacify Purify)
1987   // (at least initialize those components which we actually use)
1988   for (unsigned r=0; r<(sizeof(regs)/sizeof(regs[0])); r++) regs[r]=0;
1989 #endif
1990
1991   if (uppermost_) {
1992     function_base *func = p->findFunctionIn(pc_);
1993     if (func) {
1994       if (func->hasNoStackFrame()) { // formerly "isLeafFunc()"
1995         int proc_fd = p->getProcFileDescriptor();
1996         int lwp_fd = ioctl(proc_fd, PIOCOPENLWP, &(lwp_id_));
1997         if (-1 == lwp_fd) {
1998           cerr << "process::getCallerFrameLWP, cannot get lwp_fd" << endl ;
1999           return Frame(); // zero frame
2000         }
2001         if (ioctl(lwp_fd, PIOCGREG, &regs) != -1) {
2002           ret.pc_ = regs[R_O7] + 8;
2003           ret.fp_ = fp_; // frame pointer unchanged
2004           close(lwp_fd);
2005           return ret;
2006         }
2007         close(lwp_fd);
2008       }
2009     }
2010   }
2011
2012   //
2013   // For the sparc, register %i7 is the return address - 8 and the fp is
2014   // register %i6. These registers can be located in %fp+14*5 and
2015   // %fp+14*4 respectively, but to avoid two calls to readDataSpace,
2016   // we bring both together (i.e. 8 bytes of memory starting at %fp+14*4
2017   // or %fp+56).
2018   // These values are copied to the stack when the application is paused,
2019   // so we are assuming that the application is paused at this point
2020
2021   struct {
2022     Address fp;
2023     Address rtn;
2024   } addrs;
2025
2026   if (p->readDataSpace((caddr_t)(fp_ + 56), 2*sizeof(int)*2, 
2027                     (caddr_t)&addrs, true))
2028   {
2029     ret.fp_ = addrs.fp;
2030     ret.pc_ = addrs.rtn + 8;
2031   }
2032
2033 /*
2034   PIOCGWIN
2035        This  operation  applies  only  to SPARC machines.  p is a
2036        pointer to a gwindows_t structure, defined in <sys/reg.h>,
2037        that  is  filled with the contents of those SPARC register
2038        windows that could not be stored on the stack when the lwp
2039        stopped.   Conditions under which register windows are not
2040        stored on the stack  are:  the  stack  pointer  refers  to
2041        nonexistent process memory or the stack pointer is improp-
2042        erly aligned.  If  the  specific  or  chosen  lwp  is  not
2043        stopped, the operation returns undefined values.
2044 */
2045
2046   return ret;
2047 }
2048 #endif //MT_THREAD
2049 #endif
2050
2051 #ifdef SHM_SAMPLING
2052 time64 process::getInferiorProcessCPUtime(int lwp_id) {
2053    // returns user time from the u or proc area of the inferior process, which in
2054    // turn is presumably obtained by mmapping it (sunos) or by using a /proc ioctl
2055    // to obtain it (solaris).  It must not stop the inferior process in order
2056    // to obtain the result, nor can it assue that the inferior has been stopped.
2057    // The result MUST be "in sync" with rtinst's DYNINSTgetCPUtime().
2058
2059    // We use the PIOCUSAGE /proc ioctl
2060
2061    // Other /proc ioctls that should work too: PIOCPSINFO
2062    // and the lower-level PIOCGETPR and PIOCGETU which return copies of the proc
2063    // and u areas, respectively.
2064    // PIOCSTATUS does _not_ work because its results are not in sync
2065    // with DYNINSTgetCPUtime
2066
2067    time64 result;
2068    prusage_t theUsage;
2069
2070 #if defined(MT_THREAD)
2071    if (lwp_id != -1) {
2072      // we need to get the CPU time per LWP to be in sync with gethrvtime - naim
2073      int lwp_fd = ioctl(proc_fd, PIOCOPENLWP, &(lwp_id));
2074      if (lwp_fd == -1) {
2075        sprintf(errorLine,"Cannot read CPU time of inferior process PIOCOPENLWP, lwp_id = %d\n",
2076                lwp_id);
2077        logLine(errorLine);
2078        return 0;
2079      }  
2080      if (ioctl(lwp_fd, PIOCUSAGE, &theUsage) == -1) {
2081        perror("could not read CPU time of inferior process PIOCUSAGE");
2082        return 0;     
2083      }
2084      // we only use pr_utime in here to be in sync with gethrvtime - naim
2085      result = PDYN_mulMillion(theUsage.pr_utime.tv_sec); // sec to usec
2086      result += PDYN_div1000(theUsage.pr_utime.tv_nsec);  // nsec to usec
2087      close(lwp_fd);
2088
2089    } else {
2090 #ifdef PURE_BUILD
2091      // explicitly initialize "theUsage" struct (to pacify Purify)
2092      memset(&theUsage, '\0', sizeof(prusage_t));
2093 #endif
2094      // compute the CPU timer for the whole process
2095      if (ioctl(proc_fd, PIOCUSAGE, &theUsage) == -1) {
2096        perror("could not read CPU time of inferior PIOCUSAGE");
2097        return 0;
2098      }
2099      result = PDYN_mulMillion(theUsage.pr_utime.tv_sec); // sec to usec
2100      result += PDYN_div1000(theUsage.pr_utime.tv_nsec);  // nsec to usec
2101    }
2102 #else
2103 #ifdef PURE_BUILD
2104    // explicitly initialize "theUsage" struct (to pacify Purify)
2105    memset(&theUsage, '\0', sizeof(prusage_t));
2106 #endif
2107
2108    if (ioctl(proc_fd, PIOCUSAGE, &theUsage) == -1) {
2109       perror("could not read CPU time of inferior PIOCUSAGE");
2110       return 0;
2111    }
2112    result = PDYN_mulMillion(theUsage.pr_utime.tv_sec); // sec to usec
2113    result += PDYN_div1000(theUsage.pr_utime.tv_nsec);  // nsec to usec
2114
2115    if (result<previous) {
2116      // time shouldn't go backwards, but we have seen this happening
2117      // before, so we better check it just in case - naim 5/30/97
2118      logLine("********* time going backwards in paradynd **********\n");
2119      result=previous;
2120    } else {
2121      previous=result;
2122    }
2123 #endif   
2124
2125    return result;
2126 }
2127 #endif
2128
2129 void *process::getRegisters() {
2130    // Astonishingly, this routine can be shared between solaris/sparc and
2131    // solaris/x86.  All hail /proc!!!
2132
2133    // assumes the process is stopped (/proc requires it)
2134    assert(status_ == stopped);
2135
2136    prgregset_t theIntRegs;
2137 #ifdef PURE_BUILD
2138   // explicitly initialize "theIntRegs" struct (to pacify Purify)
2139   // (at least initialize those components which we actually use)
2140   for (unsigned r=0; r<(sizeof(theIntRegs)/sizeof(theIntRegs[0])); r++) theIntRegs[r]=0;
2141 #endif
2142
2143    if (ioctl(proc_fd, PIOCGREG, &theIntRegs) == -1) {
2144       perror("process::getRegisters PIOCGREG");
2145       if (errno == EBUSY) {
2146          cerr << "It appears that the process was not stopped in the eyes of /proc" << endl;
2147          assert(false);
2148       }
2149
2150       return NULL;
2151    }
2152
2153    prfpregset_t theFpRegs;
2154
2155    if (ioctl(proc_fd, PIOCGFPREG, &theFpRegs) == -1) {
2156       perror("process::getRegisters PIOCGFPREG");
2157       if (errno == EBUSY)
2158          cerr << "It appears that the process was not stopped in the eyes of /proc" << endl;
2159       else if (errno == EINVAL)
2160          // what to do in this case?  Probably shouldn't even do a print, right?
2161          // And it certainly shouldn't be an error, right?
2162          // But I wonder if any sparcs out there really don't have floating point.
2163          cerr << "It appears that this machine doesn't have floating-point instructions" << endl;
2164
2165       return NULL;
2166    }
2167
2168    const int numbytesPart1 = sizeof(prgregset_t);
2169    const int numbytesPart2 = sizeof(prfpregset_t);
2170    assert(numbytesPart1 % 4 == 0);
2171    assert(numbytesPart2 % 4 == 0);
2172
2173    void *buffer = new char[numbytesPart1 + numbytesPart2];
2174    assert(buffer);
2175
2176    memcpy(buffer, &theIntRegs, sizeof(theIntRegs));
2177    memcpy((char *)buffer + sizeof(theIntRegs), &theFpRegs, sizeof(theFpRegs));
2178
2179    return buffer;
2180 }
2181
2182 bool process::executingSystemCall() {
2183    prstatus theStatus;
2184 #ifdef PURE_BUILD
2185   // explicitly initialize "theStatus" struct (to pacify Purify)
2186   // (at least initialize those components which we actually use)
2187   theStatus.pr_syscall = 0;
2188 #endif
2189
2190    if (ioctl(proc_fd, PIOCSTATUS, &theStatus) != -1) {
2191      // PR_SYSEXIT is set when we have aborted a system call but not
2192      // yet continued the process.  The process in that case is not
2193      // executing a system call.  (pr_syscall is the aborted call.)
2194      if (theStatus.pr_syscall > 0 && theStatus.pr_why != PR_SYSEXIT) {
2195        if ((theStatus.pr_syscall == SYS_exit) && (theStatus.pr_why == PR_SYSENTRY)) {
2196            // entry to exit is a special case - jkh 3/16/00
2197            stoppedSyscall = SYS_exit;
2198            abortSyscall();
2199            inferiorrpc_cerr << "at entry to exit" << endl;
2200            return(false);
2201        }
2202        inferiorrpc_cerr << "pr_syscall=" << theStatus.pr_syscall << endl;
2203        return(true);
2204      }
2205    } else assert(0);
2206    return(false);
2207 }
2208
2209 bool process::changePC(Address addr, const void *savedRegs) {
2210    assert(status_ == stopped);
2211
2212    // make a copy of the registers (on purpose)
2213    prgregset_t theIntRegs;
2214    theIntRegs = *(prgregset_t*)const_cast<void*>(savedRegs);
2215
2216    theIntRegs[R_PC] = addr; // PC (sparc), EIP (x86)
2217 #ifdef R_nPC  // true for sparc, not for x86
2218    theIntRegs[R_nPC] = addr + 4;
2219 #endif
2220
2221    if (ioctl(proc_fd, PIOCSREG, &theIntRegs) == -1) {
2222       perror("process::changePC PIOCSREG failed");
2223       if (errno == EBUSY)
2224          cerr << "It appears that the process wasn't stopped in the eyes of /proc" << endl;
2225       return false;
2226    }
2227
2228    return true;
2229 }
2230
2231 bool process::changePC(Address addr) {
2232    assert(status_ == stopped); // /proc will require this
2233
2234    prgregset_t theIntRegs;
2235    if (ioctl(proc_fd, PIOCGREG, &theIntRegs) == -1) {
2236       perror("process::changePC PIOCGREG");
2237       if (errno == EBUSY) {
2238          cerr << "It appears that the process wasn't stopped in the eyes of /proc" << endl;
2239          assert(false);
2240       }
2241       return false;
2242    }
2243
2244    theIntRegs[R_PC] = addr;
2245 #ifdef R_nPC
2246    theIntRegs[R_nPC] = addr + 4;
2247 #endif
2248
2249    if (ioctl(proc_fd, PIOCSREG, &theIntRegs) == -1) {
2250       perror("process::changePC PIOCSREG");
2251       if (errno == EBUSY) {
2252          cerr << "It appears that the process wasn't stopped in the eyes of /proc" << endl;
2253          assert(false);
2254       }
2255       return false;
2256    }
2257
2258    return true;
2259 }
2260
2261 bool process::restoreRegisters(void *buffer) {
2262    // The fact that this routine can be shared between solaris/sparc and
2263    // solaris/x86 is just really, really cool.  /proc rules!
2264
2265    assert(status_ == stopped); // /proc requires it
2266
2267    prgregset_t theIntRegs; theIntRegs = *(prgregset_t *)buffer;
2268    prfpregset_t theFpRegs = * ( prfpregset_t * )( ( ( char * )buffer ) + sizeof( theIntRegs ) );
2269
2270    if (ioctl(proc_fd, PIOCSREG, &theIntRegs) == -1) {
2271       perror("process::restoreRegisters PIOCSREG failed");
2272       if (errno == EBUSY) {
2273          cerr << "It appears that the process was not stopped in the eyes of /proc" << endl;
2274          assert(false);
2275       }
2276       return false;
2277    }
2278
2279    if (ioctl(proc_fd, PIOCSFPREG, &theFpRegs) == -1) {
2280       perror("process::restoreRegisters PIOCSFPREG failed");
2281       if (errno == EBUSY) {
2282          cerr << "It appears that the process was not stopped in the eyes of /proc" << endl;
2283          assert(false);
2284       }
2285       return false;
2286    }
2287
2288    return true;
2289 }
2290
2291 #ifdef i386_unknown_solaris2_5
2292
2293 Frame Frame::getCallerFrameNormal(process *p) const
2294 {
2295   //
2296   // for the x86, the frame-pointer (EBP) points to the previous frame-pointer,
2297   // and the saved return address is in EBP-4.
2298   //
2299   struct {
2300     Address fp;
2301     Address rtn;
2302   } addrs;
2303
2304   if (p->readDataSpace((caddr_t)(fp_), 2*sizeof(int),
2305                        (caddr_t)&addrs, true)) 
2306   {
2307     Frame ret;
2308     ret.fp_ = addrs.fp;
2309     ret.pc_ = addrs.rtn;
2310     return ret;
2311   }
2312   
2313   return Frame(); // zero frame
2314 }
2315
2316 #endif
2317
2318 #ifdef i386_unknown_solaris2_5
2319 // ******** TODO **********
2320 bool process::needToAddALeafFrame(Frame , Address &) {
2321   return false;
2322 }
2323
2324 #else
2325
2326 // needToAddALeafFrame: returns true if the between the current frame 
2327 // and the next frame there is a leaf function (this occurs when the 
2328 // current frame is the signal handler and the function that was executing
2329 // when the sighandler was called is a leaf function)
2330 bool process::needToAddALeafFrame(Frame current_frame, Address &leaf_pc){
2331
2332    // check to see if the current frame is the signal handler 
2333    Address frame_pc = current_frame.getPC();
2334    Address sig_addr = 0;
2335    const image *sig_image = (signal_handler->file())->exec();
2336    if(getBaseAddress(sig_image, sig_addr)){
2337        sig_addr += signal_handler->getAddress(0);
2338    } else {
2339        sig_addr = signal_handler->getAddress(0);
2340    }
2341    u_int sig_size = signal_handler->size();
2342    if(signal_handler&&(frame_pc >= sig_addr)&&(frame_pc < (sig_addr+sig_size))){
2343        // get the value of the saved PC: this value is stored in the address
2344        // specified by the value in register i2 + 44. Register i2 must contain
2345        // the address of some struct that contains, among other things, the 
2346        // saved PC value.  
2347        u_int reg_i2;
2348        int fp = current_frame.getFP();
2349        if (readDataSpace((caddr_t)(fp+40),sizeof(u_int),(caddr_t)&reg_i2,true)){
2350           if (readDataSpace((caddr_t) (reg_i2+44), sizeof(int),
2351                             (caddr_t) &leaf_pc,true)){
2352               // if the function is a leaf function return true
2353               function_base *func = findFunctionIn(leaf_pc);
2354               if(func && func->hasNoStackFrame()) { // formerly "isLeafFunc()"
2355                   return(true);
2356               }
2357           }
2358       }
2359    }
2360    return false;
2361 }
2362 #endif
2363
2364 string process::tryToFindExecutable(const string &iprogpath, int pid) {
2365    // returns empty string on failure.
2366    // Otherwise, returns a full-path-name for the file.  Tries every
2367    // trick to determine the full-path-name, even though "progpath" may be
2368    // unspecified (empty string).
2369    
2370    // Remember, we can always return the empty string...no need to
2371    // go nuts writing the world's most complex algorithm.
2372
2373    attach_cerr << "welcome to tryToFindExecutable; progpath=" << iprogpath << ", pid=" << pid << endl;
2374
2375    const string progpath = expand_tilde_pathname(iprogpath);
2376
2377    // Trivial case: if "progpath" is specified and the file exists then nothing needed
2378    if (exists_executable(progpath)) {
2379       attach_cerr << "tryToFindExecutable succeeded immediately, returning "
2380                   << progpath << endl;
2381       return progpath;
2382    }
2383
2384    attach_cerr << "tryToFindExecutable failed on filename " << progpath << endl;
2385
2386    char buffer[128];
2387    sprintf(buffer, "/proc/%05d", pid);
2388    int procfd = open(buffer, O_RDONLY, 0);
2389    if (procfd == -1) {
2390       attach_cerr << "tryToFindExecutable failed since open of /proc failed" << endl;
2391       return "";
2392    }
2393    attach_cerr << "tryToFindExecutable: opened /proc okay" << endl;
2394
2395    string argv0, path, cwd;
2396    if (get_ps_stuff(procfd, argv0, path, cwd)) {
2397        // the following routine is implemented in the util lib.
2398        string result;
2399        if (executableFromArgv0AndPathAndCwd(result, argv0, path, cwd)) {
2400           (void)close(procfd);
2401           return result;
2402        }
2403    }
2404
2405    attach_cerr << "tryToFindExecutable: giving up" << endl;
2406
2407    (void)close(procfd);
2408    return "";
2409 }
2410
2411 bool process::set_breakpoint_for_syscall_completion() {
2412    /* Can assume: (1) process is paused and (2) in a system call.
2413       We want to set a TRAP for the syscall exit, and do the
2414       inferiorRPC at that time.  We'll use /proc PIOCSEXIT.
2415       Returns true iff breakpoint was successfully set. */
2416
2417    sysset_t save_exitset;
2418    if (-1 == ioctl(proc_fd, PIOCGEXIT, &save_exitset))
2419       return false;
2420
2421    sysset_t new_exit_set;
2422    prfillset(&new_exit_set);
2423    if (-1 == ioctl(proc_fd, PIOCSEXIT, &new_exit_set))
2424       return false;
2425
2426    assert(save_exitset_ptr == NULL);
2427    save_exitset_ptr = new sysset_t;
2428    memcpy(save_exitset_ptr, &save_exitset, sizeof(save_exitset));
2429
2430    return true;
2431 }
2432
2433 void process::clear_breakpoint_for_syscall_completion() { return; }
2434
2435 Address process::read_inferiorRPC_result_register(Register) {
2436
2437    prgregset_t theIntRegs;
2438 #ifdef PURE_BUILD
2439   // explicitly initialize "theIntRegs" struct (to pacify Purify)
2440   for (unsigned r=0; r<(sizeof(theIntRegs)/sizeof(theIntRegs[0])); r++)
2441       theIntRegs[r]=0;
2442 #endif
2443
2444    if (-1 == ioctl(proc_fd, PIOCGREG, &theIntRegs)) {
2445       perror("process::read_inferiorRPC_result_register PIOCGREG");
2446       if (errno == EBUSY) {
2447          cerr << "It appears that the process was not stopped in the eyes of /proc" << endl;
2448          assert(false);
2449       }
2450       return 0; // assert(false)?
2451    }
2452
2453    // on x86, the result is always stashed in %EAX; on sparc, it's always %o0.
2454    // In neither case do we need the argument of this fn.
2455 #ifdef i386_unknown_solaris2_5
2456    return theIntRegs[EAX];
2457 #else
2458    return theIntRegs[R_O0];
2459 #endif
2460 }
2461
2462 void print_read_error_info(const relocationEntry entry, 
2463       pd_Function *&target_pdf, Address base_addr) {
2464
2465     sprintf(errorLine, "  entry      : target_addr 0x%lx\n",
2466             entry.target_addr());
2467     logLine(errorLine);
2468     sprintf(errorLine, "               rel_addr 0x%lx\n", entry.rel_addr());
2469     logLine(errorLine);
2470     sprintf(errorLine, "               name %s\n", (entry.name()).string_of());
2471     logLine(errorLine);
2472
2473     if (target_pdf) {
2474       sprintf(errorLine, "  target_pdf : symTabName %s\n",
2475               (target_pdf->symTabName()).string_of());
2476       logLine(errorLine);    
2477       sprintf(errorLine , "              prettyName %s\n",
2478               (target_pdf->symTabName()).string_of());
2479       logLine(errorLine);
2480       sprintf(errorLine , "              size %i\n",
2481               target_pdf->size());
2482       logLine(errorLine);
2483       sprintf(errorLine , "              addr 0x%lx\n",
2484               target_pdf->addr());
2485       logLine(errorLine);
2486     }
2487
2488     sprintf(errorLine, "  base_addr  0x%lx\n", base_addr);
2489     logLine(errorLine);
2490 }
2491
2492 // hasBeenBound: returns true if the runtime linker has bound the
2493 // function symbol corresponding to the relocation entry in at the address
2494 // specified by entry and base_addr.  If it has been bound, then the callee 
2495 // function is returned in "target_pdf", else it returns false.
2496 bool process::hasBeenBound(const relocationEntry entry, 
2497                            pd_Function *&target_pdf, Address base_addr) {
2498
2499 // TODO: the x86 and sparc versions should really go in seperate files 
2500 #if defined(i386_unknown_solaris2_5)
2501
2502     if (status() == exited) return false;
2503
2504     // if the relocationEntry has not been bound yet, then the value
2505     // at rel_addr is the address of the instruction immediately following
2506     // the first instruction in the PLT entry (which is at the target_addr) 
2507     // The PLT entries are never modified, instead they use an indirrect 
2508     // jump to an address stored in the _GLOBAL_OFFSET_TABLE_.  When the 
2509     // function symbol is bound by the runtime linker, it changes the address
2510     // in the _GLOBAL_OFFSET_TABLE_ corresponding to the PLT entry
2511
2512     Address got_entry = entry.rel_addr() + base_addr;
2513     Address bound_addr = 0;
2514     if(!readDataSpace((const void*)got_entry, sizeof(Address), 
2515                         &bound_addr, true)){
2516         sprintf(errorLine, "read error in process::hasBeenBound "
2517                 "addr 0x%lx, pid=%d\n (readDataSpace returns 0)",
2518                 got_entry, pid);
2519         logLine(errorLine);
2520         print_read_error_info(entry, target_pdf, base_addr);
2521         return false;
2522     }
2523
2524     if( !( bound_addr == (entry.target_addr()+6+base_addr)) ) {
2525         // the callee function has been bound by the runtime linker
2526         // find the function and return it
2527         target_pdf = findpdFunctionIn(bound_addr);
2528         if(!target_pdf){
2529             return false;
2530         }
2531         return true;    
2532     }
2533     return false;
2534
2535 #else
2536     // if the relocationEntry has not been bound yet, then the second instr 
2537     // in this PLT entry branches to the fist PLT entry.  If it has been   
2538     // bound, then second two instructions of the PLT entry have been changed 
2539     // by the runtime linker to jump to the address of the function.  
2540     // Here is an example:   
2541     //     before binding                       after binding
2542     //     --------------                       -------------
2543     //     sethi  %hi(0x15000), %g1             sethi  %hi(0x15000), %g1
2544     //     b,a  <_PROCEDURE_LINKAGE_TABLE_>     sethi  %hi(0xef5eb000), %g1
2545     //     nop                                  jmp  %g1 + 0xbc ! 0xef5eb0bc
2546
2547     instruction next_insn;
2548     Address next_insn_addr = entry.target_addr() + base_addr + 4; 
2549     if( !(readDataSpace((caddr_t)next_insn_addr, sizeof(next_insn), 
2550                        (char *)&next_insn, true)) ) {
2551         sprintf(errorLine, "read error in process::hasBeenBound addr 0x%lx"
2552                 " (readDataSpace next_insn_addr returned 0)\n",
2553                 next_insn_addr);
2554         logLine(errorLine);
2555         print_read_error_info(entry, target_pdf, base_addr);
2556     }
2557     // if this is a b,a instruction, then the function has not been bound
2558     if((next_insn.branch.op == FMT2op)  && (next_insn.branch.op2 == BICCop2) 
2559        && (next_insn.branch.anneal == 1) && (next_insn.branch.cond == BAcond)) {
2560         return false;
2561     } 
2562
2563     // if this is a sethi instruction, then it has been bound...get target_addr
2564     instruction third_insn;
2565     Address third_addr = entry.target_addr() + base_addr + 8; 
2566     if( !(readDataSpace((caddr_t)third_addr, sizeof(third_insn), 
2567                        (char *)&third_insn, true)) ) {
2568         sprintf(errorLine, "read error in process::hasBeenBound addr 0x%lx"
2569                 " (readDataSpace third_addr returned 0)\n",
2570                 third_addr);
2571         logLine(errorLine);
2572         print_read_error_info(entry,target_pdf, base_addr);
2573     }
2574
2575     // get address of bound function, and return the corr. pd_Function
2576     if((next_insn.sethi.op == FMT2op) && (next_insn.sethi.op2 == SETHIop2)
2577         && (third_insn.rest.op == RESTop) && (third_insn.rest.i == 1)
2578         && (third_insn.rest.op3 == JMPLop3)) {
2579         
2580         Address new_target = (next_insn.sethi.imm22 << 10) & 0xfffffc00; 
2581         new_target |= third_insn.resti.simm13;
2582
2583         target_pdf = findpdFunctionIn(new_target);
2584         if(!target_pdf){
2585             return false;
2586         }
2587         return true;
2588     }
2589     // this is a messed up entry
2590     return false;
2591 #endif
2592
2593 }
2594
2595
2596
2597 // findCallee: finds the function called by the instruction corresponding
2598 // to the instPoint "instr". If the function call has been bound to an
2599 // address, then the callee function is returned in "target" and the 
2600 // instPoint "callee" data member is set to pt to callee's function_base.  
2601 // If the function has not yet been bound, then "target" is set to the 
2602 // function_base associated with the name of the target function (this is 
2603 // obtained by the PLT and relocation entries in the image), and the instPoint
2604 // callee is not set.  If the callee function cannot be found, (ex. function
2605 // pointers, or other indirect calls), it returns false.
2606 // Returns false on error (ex. process doesn't contain this instPoint).
2607 //
2608 // The assumption here is that for all processes sharing the image containing
2609 // this instPoint they are going to bind the call target to the same function. 
2610 // For shared objects this is always true, however this may not be true for
2611 // dynamic executables.  Two a.outs can be identical except for how they are
2612 // linked, so a call to fuction foo in one version of the a.out may be bound
2613 // to function foo in libfoo.so.1, and in the other version it may be bound to 
2614 // function foo in libfoo.so.2.  We are currently not handling this case, since
2615 // it is unlikely to happen in practice.
2616 bool process::findCallee(instPoint &instr, function_base *&target){
2617     
2618     if((target = const_cast<function_base *>(instr.iPgetCallee()))) {
2619         return true; // callee already set
2620     }
2621
2622     // find the corresponding image in this process  
2623     const image *owner = instr.iPgetOwner();
2624     bool found_image = false;
2625     Address base_addr = 0;
2626     if(symbols == owner) {  found_image = true; } 
2627     else if(shared_objects){
2628         for(u_int i=0; i < shared_objects->size(); i++){
2629             if(owner == ((*shared_objects)[i])->getImage()) {
2630                 found_image = true;
2631                 base_addr = ((*shared_objects)[i])->getBaseAddress();
2632                 break;
2633             }
2634         }
2635     } 
2636     if(!found_image) {
2637         target = 0;
2638         return false; // image not found...this is bad
2639     }
2640
2641     // get the target address of this function
2642     Address target_addr = 0;
2643 //    Address insn_addr = instr.iPgetAddress(); 
2644     target_addr = instr.getTargetAddress();
2645
2646     if(!target_addr) {  
2647         // this is either not a call instruction or an indirect call instr
2648         // that we can't get the target address
2649         target = 0;
2650         return false;
2651     }
2652
2653 #if defined(sparc_sun_solaris2_4)
2654     // If this instPoint is from a function that was relocated to the heap
2655     // then need to get the target address relative to this image   
2656     if(target_addr && instr.relocated_) {
2657         assert(target_addr > base_addr);
2658         target_addr -= base_addr;
2659     }
2660 #endif
2661
2662     // see if there is a function in this image at this target address
2663     // if so return it
2664     pd_Function *pdf = 0;
2665     if( (pdf = owner->findFunctionInInstAndUnInst(target_addr,this)) ) {
2666         target = pdf;
2667         instr.set_callee(pdf);
2668         return true; // target found...target is in this image
2669     }
2670
2671     // else, get the relocation information for this image
2672     const Object &obj = owner->getObject();
2673     const vector<relocationEntry> *fbt;
2674     if(!obj.get_func_binding_table_ptr(fbt)) {
2675         target = 0;
2676         return false; // target cannot be found...it is an indirect call.
2677     }
2678
2679     // find the target address in the list of relocationEntries
2680     for(u_int i=0; i < fbt->size(); i++) {
2681         if((*fbt)[i].target_addr() == target_addr) {
2682             // check to see if this function has been bound yet...if the
2683             // PLT entry for this function has been modified by the runtime
2684             // linker
2685             pd_Function *target_pdf = 0;
2686             if(hasBeenBound((*fbt)[i], target_pdf, base_addr)) {
2687                 target = target_pdf;
2688                 instr.set_callee(target_pdf);
2689                 return true;  // target has been bound
2690             } 
2691             else {
2692                 // just try to find a function with the same name as entry 
2693                 target = findOneFunctionFromAll((*fbt)[i].name());
2694                 if(target){
2695                     return true;
2696                 }
2697                 else {  
2698                     // KLUDGE: this is because we are not keeping more than
2699                     // one name for the same function if there is more
2700                     // than one.  This occurs when there are weak symbols
2701                     // that alias global symbols (ex. libm.so.1: "sin" 
2702                     // and "__sin").  In most cases the alias is the same as 
2703                     // the global symbol minus one or two leading underscores,
2704                     // so here we add one or two leading underscores to search
2705                     // for the name to handle the case where this string 
2706                     // is the name of the weak symbol...this will not fix 
2707                     // every case, since if the weak symbol and global symbol
2708                     // differ by more than leading underscores we won't find
2709                     // it...when we parse the image we should keep multiple
2710                     // names for pd_Functions
2711
2712                     string s = string("_");
2713                     s += (*fbt)[i].name();
2714                     target = findOneFunctionFromAll(s);
2715                     if(target){
2716                         return true;
2717                     }
2718                     s = string("__");
2719                     s += (*fbt)[i].name();
2720                     target = findOneFunctionFromAll(s);
2721                     if(target){
2722                         return true;
2723                     }
2724                 }
2725             }
2726             target = 0;
2727             return false;
2728         }
2729     }
2730     target = 0;
2731     return false;  
2732 }
2733
2734 #if defined(MT_THREAD) 
2735 pdThread *process::createThread(
2736   int tid, 
2737   unsigned pos, 
2738   unsigned stackbase, 
2739   unsigned startpc, 
2740   void* resumestate_p,  
2741   bool bySelf)
2742 {
2743   pdThread *thr;
2744
2745   // creating new thread
2746   thr = new pdThread(this, tid, pos);
2747   threads += thr;
2748
2749   unsigned pd_pos;
2750   if(!threadMap->add(tid,pd_pos)) {
2751     // we run out of space, so we should try to get some more - naim
2752     if (getTable().increaseMaxNumberOfThreads()) {
2753       if (!threadMap->add(tid,pd_pos)) {
2754         // we should be able to add more threads! - naim
2755         assert(0);
2756       }
2757     } else {
2758       // we completely run out of space! - naim
2759       assert(0);
2760     }
2761   }
2762   thr->update_pd_pos(pd_pos);
2763   thr->update_resumestate_p(resumestate_p);
2764   function_base *pdf ;
2765
2766   if (startpc) {
2767     thr->update_stack_addr(stackbase) ;
2768     thr->update_start_pc(startpc) ;
2769     pdf = findFunctionIn(startpc) ;
2770     thr->update_start_func(pdf) ;
2771   } else {
2772     pdf = findOneFunction("main");
2773     assert(pdf);
2774     //thr->update_start_pc(pdf->addr()) ;
2775     thr->update_start_pc(0);
2776     thr->update_start_func(pdf) ;
2777
2778     prstatus_t theStatus;
2779     if (ioctl(proc_fd, PIOCSTATUS, &theStatus) != -1) {
2780       thr->update_stack_addr((stackbase=(unsigned)theStatus.pr_stkbase));
2781     } else {
2782       assert(0);
2783     }
2784   }
2785
2786   getTable().addThread(thr);
2787
2788   //  
2789   sprintf(errorLine,"+++++ creating new thread{%s}, pd_pos=%u, pos=%u, tid=%d, stack=0x%x, resumestate=0x%x, by[%s]\n",
2790           pdf->prettyName().string_of(), pd_pos,pos,tid,stackbase,resumestate_p, bySelf?"Self":"Parent");
2791   logLine(errorLine);
2792
2793   return(thr);
2794 }
2795
2796 //
2797 // CALLED for mainThread
2798 //
2799 void process::updateThread(pdThread *thr, int tid, unsigned pos, void* resumestate_p, resource *rid) {
2800   unsigned pd_pos;
2801   assert(thr);
2802   thr->update_tid(tid, pos);
2803   assert(threadMap);
2804   if(!threadMap->add(tid,pd_pos)) {
2805     // we run out of space, so we should try to get some more - naim
2806     if (getTable().increaseMaxNumberOfThreads()) {
2807       if (!threadMap->add(tid,pd_pos)) {
2808         // we should be able to add more threads! - naim
2809         assert(0);
2810       }
2811     } else {
2812       // we completely run out of space! - naim
2813       assert(0);
2814     }
2815   }
2816   thr->update_pd_pos(pd_pos);
2817   thr->update_rid(rid);
2818   thr->update_resumestate_p(resumestate_p);
2819   function_base *f_main = findOneFunction("main");
2820   assert(f_main);
2821
2822   //unsigned addr = f_main->addr();
2823   //thr->update_start_pc(addr) ;
2824   thr->update_start_pc(0) ;
2825   thr->update_start_func(f_main) ;
2826
2827   prstatus_t theStatus;
2828   if (ioctl(proc_fd, PIOCSTATUS, &theStatus) != -1) {
2829     thr->update_stack_addr((unsigned)theStatus.pr_stkbase);
2830   } else {
2831     assert(0);
2832   }
2833
2834   sprintf(errorLine,"+++++ updateThread--> creating new thread{main}, pd_pos=%u, pos=%u, tid=%d, stack=0x%x, resumestate=0x%x\n",pd_pos,pos,tid,theStatus.pr_stkbase, resumestate_p);
2835   logLine(errorLine);
2836 }
2837
2838 //
2839 // CALLED from Attach
2840 //
2841 void process::updateThread(
2842   pdThread *thr, 
2843   int tid, 
2844   unsigned pos, 
2845   unsigned stackbase, 
2846   unsigned startpc, 
2847   void* resumestate_p) 
2848 {
2849   unsigned pd_pos;
2850   assert(thr);
2851   //  
2852   sprintf(errorLine," updateThread(tid=%d, pos=%d, stackaddr=0x%x, startpc=0x%x)\n",
2853          tid, pos, stackbase, startpc);
2854   logLine(errorLine);
2855
2856   thr->update_tid(tid, pos);
2857   assert(threadMap);
2858   if(!threadMap->add(tid,pd_pos)) {
2859     // we run out of space, so we should try to get some more - naim
2860     if (getTable().increaseMaxNumberOfThreads()) {
2861       if (!threadMap->add(tid,pd_pos)) {
2862         // we should be able to add more threads! - naim
2863         assert(0);
2864       }
2865     } else {
2866       // we completely run out of space! - naim
2867       assert(0);
2868     }
2869   }
2870
2871   thr->update_pd_pos(pd_pos);
2872   thr->update_resumestate_p(resumestate_p);
2873
2874   function_base *pdf;
2875
2876   if(startpc) {
2877     thr->update_start_pc(startpc) ;
2878     pdf = findFunctionIn(startpc) ;
2879     thr->update_start_func(pdf) ;
2880     thr->update_stack_addr(stackbase) ;
2881   } else {
2882     pdf = findOneFunction("main");
2883     assert(pdf);
2884     thr->update_start_pc(startpc) ;
2885     //thr->update_start_pc(pdf->addr()) ;
2886     thr->update_start_func(pdf) ;
2887
2888     prstatus_t theStatus;
2889     if (ioctl(proc_fd, PIOCSTATUS, &theStatus) != -1) {
2890       thr->update_stack_addr((stackbase=(unsigned)theStatus.pr_stkbase));
2891     } else {
2892       assert(0);
2893     }
2894   } //else
2895
2896   sprintf(errorLine,"+++++ creating new thread{%s}, pd_pos=%u, pos=%u, tid=%d, stack=0x%xs, resumestate=0x%x\n",
2897     pdf->prettyName().string_of(), pd_pos, pos, tid, stackbase, resumestate_p);
2898   logLine(errorLine);
2899 }
2900
2901 void process::deleteThread(int tid)
2902 {
2903   pdThread *thr=NULL;
2904   unsigned i;
2905
2906   for (i=0;i<threads.size();i++) {
2907     if (threads[i]->get_tid() == tid) {
2908       thr = threads[i];
2909       break;
2910     }   
2911   }
2912   if (thr != NULL) {
2913     getTable().deleteThread(thr);
2914     unsigned theSize = threads.size();
2915     threads[i] = threads[theSize-1];
2916     threads.resize(theSize-1);
2917     delete thr;    
2918     sprintf(errorLine,"----- deleting thread, tid=%d, threads.size()=%d\n",tid,threads.size());
2919     logLine(errorLine);
2920   }
2921 }
2922 #endif
2923