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