Fixing race condition between inferiorRPC waiting for a system call to
[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 #include "dyninstAPI/src/symtab.h"
43 #include "util/h/headers.h"
44 #include "dyninstAPI/src/os.h"
45 #include "dyninstAPI/src/process.h"
46 #include "dyninstAPI/src/stats.h"
47 #include "util/h/Types.h"
48 #include <sys/ioctl.h>
49 #include <fcntl.h>
50 #include <sys/termios.h>
51 #include <unistd.h>
52 #include "paradynd/src/showerror.h"
53 #include "util/h/pathName.h" // concat_pathname_components()
54 #include "util/h/debugOstream.h"
55 #include "util/h/solarisKludges.h"
56
57 #if defined (sparc_sun_solaris2_4)
58 #include "dyninstAPI/src/inst-sparc.h"
59 #else
60 #include "dyninstAPI/src/inst-x86.h"
61 #endif
62
63 #include "instPoint.h"
64
65 #include <sys/procfs.h>
66 #include <poll.h>
67 #include <limits.h>
68 #include <link.h>
69
70 extern "C" {
71 extern int ioctl(int, int, ...);
72 extern long sysconf(int);
73 };
74
75 // The following were defined in process.C
76 extern debug_ostream attach_cerr;
77 extern debug_ostream inferiorrpc_cerr;
78 extern debug_ostream shmsample_cerr;
79 extern debug_ostream forkexec_cerr;
80 extern debug_ostream metric_cerr;
81 extern debug_ostream signal_cerr;
82
83 /*
84    Define the indices of some registers to be used with pr_reg.
85    These values are different on sparc and x86 platforms.
86    RETVAL_REG: the registers that holds the return value of calls ($o0 on sparc,
87                %eax on x86).
88    PC_REG: program counter
89    FP_REG: frame pointer (%i7 on sparc, %ebp on x86) 
90 */
91 #ifdef sparc_sun_solaris2_4
92 #define RETVAL_REG (R_O0)
93 #define PC_REG (R_PC)
94 #define FP_REG (R_O6)
95 #endif
96 #ifdef i386_unknown_solaris2_5
97 #define RETVAL_REG (EAX)
98 #define PC_REG (EIP)
99 #define FP_REG (EBP)
100 #endif
101
102
103 extern bool isValidAddress(process *proc, Address where);
104
105 /*
106    osTraceMe is called after we fork a child process to set
107    a breakpoint on the exit of the exec system call.
108    When /proc is used, this breakpoint **will not** cause a SIGTRAP to 
109    be sent to the process. The parent should use PIOCWSTOP to wait for 
110    the child.
111 */
112 void OS::osTraceMe(void) {
113   sysset_t exitSet;
114   char procName[128];
115
116   sprintf(procName,"/proc/%05d", (int)getpid());
117   int fd = P_open(procName, O_RDWR, 0);
118   if (fd < 0) {
119     fprintf(stderr, "osTraceMe: open failed: %s\n", sys_errlist[errno]); 
120     fflush(stderr);
121     P__exit(-1); // must use _exit here.
122   }
123
124   /* set a breakpoint at the exit of exec/execve */
125   premptyset(&exitSet);
126   praddset(&exitSet, SYS_exec);
127   praddset(&exitSet, SYS_execve);
128
129   if (ioctl(fd, PIOCSEXIT, &exitSet) < 0) {
130     fprintf(stderr, "osTraceMe: PIOCSEXIT failed: %s\n", sys_errlist[errno]); 
131     fflush(stderr);
132     P__exit(-1); // must use _exit here.
133   }
134
135   errno = 0;
136   close(fd);
137   return;
138 }
139
140
141 // already setup on this FD.
142 // disconnect from controlling terminal 
143 void OS::osDisconnect(void) {
144   int ttyfd = open ("/dev/tty", O_RDONLY);
145   ioctl (ttyfd, TIOCNOTTY, NULL); 
146   P_close (ttyfd);
147 }
148
149 bool process::continueWithForwardSignal(int) {
150    if (-1 == ioctl(proc_fd, PIOCRUN, NULL)) {
151       perror("could not forward signal in PIOCRUN");
152       return false;
153    }
154
155    return true;
156 }
157
158 bool process::dumpImage() {return false;}
159
160
161 /* 
162    execResult: return the result of an exec system call - true if succesful.
163    The traced processes will stop on exit of an exec system call, just before
164    returning to user code. At this point the return value (errno) is already
165    written to a register, and we need to check if the return value is zero.
166  */
167 static inline bool execResult(prstatus_t stat) {
168   return (stat.pr_reg[RETVAL_REG] == 0);
169 }
170
171 /*
172    wait for inferior processes to terminate or stop.
173 */
174 int process::waitProcs(int *status) {
175    extern vector<process*> processVec;
176
177    static struct pollfd fds[OPEN_MAX];  // argument for poll
178    static int selected_fds;             // number of selected
179    static int curr;                     // the current element of fds
180
181    /* Each call to poll may return many selected fds. Since we only report the status
182       of one process per each call to waitProcs, we keep the result of the last
183       poll buffered, and simply process an element from the buffer until all of
184       the selected fds in the last poll have been processed.
185    */
186
187    if (selected_fds == 0) {
188      for (unsigned u = 0; u < processVec.size(); u++) {
189        if (processVec[u] && (processVec[u]->status() == running || processVec[u]->status() == neonatal))
190          fds[u].fd = processVec[u]->proc_fd;
191        else
192          fds[u].fd = -1;
193        fds[u].events = POLLPRI;
194        fds[u].revents = 0;
195      }
196
197      selected_fds = poll(fds, processVec.size(), 0);
198      if (selected_fds < 0) {
199        fprintf(stderr, "waitProcs: poll failed: %s\n", sys_errlist[errno]);
200        selected_fds = 0;
201        return 0;
202      }
203
204      curr = 0;
205    }
206    
207    if (selected_fds > 0) {
208      while (fds[curr].revents == 0)
209        ++curr;
210
211      // fds[curr] has an event of interest
212      prstatus_t stat;
213      int ret = 0;
214
215      if (ioctl(fds[curr].fd, PIOCSTATUS, &stat) != -1 
216          && ((stat.pr_flags & PR_STOPPED) || (stat.pr_flags & PR_ISTOP))) {
217        switch (stat.pr_why) {
218        case PR_SIGNALLED:
219          // return the signal number
220          *status = stat.pr_what << 8 | 0177;
221          ret = processVec[curr]->getPid();
222          break;
223        case PR_SYSEXIT: {
224          // exit of a system call.
225          process *p = processVec[curr];
226
227          if (p->RPCs_waiting_for_syscall_to_complete) {
228             // reset PIOCSEXIT mask
229             inferiorrpc_cerr << "solaris got PR_SYSEXIT!" << endl;
230             assert(p->save_exitset_ptr != NULL);
231             if (-1 == ioctl(p->proc_fd, PIOCSEXIT, p->save_exitset_ptr))
232                assert(false);
233             delete [] p->save_exitset_ptr;
234             p->save_exitset_ptr = NULL;
235
236             // fall through on purpose (so status, ret get set)
237          }
238          else if (!execResult(stat)) {
239            // a failed exec. continue the process
240            processVec[curr]->continueProc_();
241            break;
242          }          
243
244          *status = SIGTRAP << 8 | 0177;
245          ret = processVec[curr]->getPid();
246          break;
247        }
248        case PR_REQUESTED:
249          assert(0);
250        case PR_JOBCONTROL:
251          assert(0);
252          break;
253        }        
254       }
255
256      --selected_fds;
257      ++curr;
258
259      if (ret > 0) {
260        return ret;
261      }
262    }
263
264    return waitpid(0, status, WNOHANG);
265 }
266
267
268 static char *extract_string_ptr(int procfd, char **ptr) {
269    // we want to return *ptr.
270
271    if (-1 == lseek(procfd, (long)ptr, SEEK_SET))
272       assert(false);
273
274    char *result;
275    if (-1 == read(procfd, &result, sizeof(result)))
276       assert(false);
277
278    return result;   
279 }
280
281 string extract_string(int procfd, const char *inferiorptr) {
282    // assuming inferiorptr points to a null-terminated string in the inferior
283    // process, extract it and return it.
284
285    if (-1 == lseek(procfd, (long)inferiorptr, SEEK_SET))
286       return "";
287
288    string result;
289    while (true) {
290       char buffer[100];
291       if (-1 == read(procfd, &buffer, 80))
292          return "";
293       buffer[80] = '\0';
294       result += buffer;
295
296       // was there a '\0' anywhere in chars 0 thru 79?  If so then
297       // we're done
298       for (unsigned lcv=0; lcv < 80; lcv++)
299          if (buffer[lcv] == '\0') {
300             //attach_cerr << "extract_string returning " << result << endl;
301             return result;
302          }
303    }
304 }
305
306 void get_ps_stuff(int proc_fd, string &argv0, string &pathenv, string &cwdenv) {
307    // Use ps info to obtain argv[0], PATH, and curr working directory of the
308    // inferior process designated by proc_fd.  Writes to argv0, pathenv, cwdenv.
309
310    prpsinfo the_psinfo;
311    if (-1 == ioctl(proc_fd, PIOCPSINFO, &the_psinfo))
312       assert(false);
313
314    // get argv[0].  It's in the_psinfo.pr_argv[0], but that's a ptr in the inferior
315    // space, so we need to /proc read() it out.  Also, the_psinfo.pr_argv is a char **
316    // not a char* so we even need to /proc read() to get a pointer value.  Ick.
317    assert(the_psinfo.pr_argv != NULL);
318    char *ptr_to_argv0 = extract_string_ptr(proc_fd, the_psinfo.pr_argv);
319    argv0 = extract_string(proc_fd, ptr_to_argv0);
320
321    // Get the PWD and PATH environment variables from the application.
322    char **envptr = the_psinfo.pr_envp;
323    while (true) {
324       // dereference envptr; check for NULL
325       char *env = extract_string_ptr(proc_fd, envptr);
326       if (env == NULL)
327          break;
328
329       string env_value = extract_string(proc_fd, env);
330       if (env_value.prefixed_by("PWD=") || env_value.prefixed_by("CWD=")) {
331          cwdenv = env_value.string_of() + 4; // skip past "PWD=" or "CWD="
332          attach_cerr << "get_ps_stuff: using PWD value of: " << cwdenv << endl;
333       }
334       else if (env_value.prefixed_by("PATH=")) {
335          pathenv = env_value.string_of() + 5; // skip past the "PATH="
336          attach_cerr << "get_ps_stuff: using PATH value of: " << pathenv << endl;
337       }
338
339       envptr++;
340    }
341 }
342
343 /*
344    Open the /proc file correspoding to process pid, 
345    set the signals to be caught to be only SIGSTOP and SIGTRAP,
346    and set the kill-on-last-close and inherit-on-fork flags.
347 */
348 extern string pd_flavor ;
349 bool process::attach() {
350   char procName[128];
351
352   // QUESTION: does this attach operation lead to a SIGTRAP being forwarded
353   // to paradynd in all cases?  How about when we are attaching to an
354   // already-running process?  (Seems that in the latter case, no SIGTRAP
355   // is automatically generated)
356
357   // step 1) /proc open: attach to the inferior process
358   sprintf(procName,"/proc/%05d", (int)pid);
359   int fd = P_open(procName, O_RDWR, 0);
360   if (fd < 0) {
361     fprintf(stderr, "attach: open failed: %s\n", sys_errlist[errno]);
362     return false;
363   }
364
365   // step 2) /proc PIOCSTRACE: define which signals should be forwarded to daemon
366   //   These are (1) SIGSTOP and (2) either SIGTRAP (sparc) or SIGILL (x86), to
367   //   implement inferiorRPC completion detection.
368   sigset_t sigs;
369   premptyset(&sigs);
370   praddset(&sigs, SIGSTOP);
371
372 #ifndef i386_unknown_solaris2_5
373   praddset(&sigs, SIGTRAP);
374 #endif
375
376 #ifdef i386_unknown_solaris2_5
377   praddset(&sigs, SIGILL);
378 #endif
379
380   if (ioctl(fd, PIOCSTRACE, &sigs) < 0) {
381     fprintf(stderr, "attach: ioctl failed: %s\n", sys_errlist[errno]);
382     close(fd);
383     return false;
384   }
385
386   // Step 3) /proc PIOCSET:
387   // a) turn on the kill-on-last-close flag (kills inferior with SIGKILL when
388   //    the last writable /proc fd closes)
389   // b) turn on inherit-on-fork flag (tracing flags inherited when child forks).
390   // c) turn on breakpoint trap pc adjustment (x86 only).
391   // Also, any child of this process will stop at the exit of an exec call.
392
393   //Tempest, do not need to inherit-on-fork
394   long flags ;
395   if(process::pdFlavor == string("cow"))
396         flags = PR_KLC |  PR_BPTADJ;
397   else
398         flags = PR_KLC | PR_FORK | PR_BPTADJ;
399   if (ioctl (fd, PIOCSET, &flags) < 0) {
400     fprintf(stderr, "attach: PIOCSET failed: %s\n", sys_errlist[errno]);
401     close(fd);
402     return false;
403   }
404
405   proc_fd = fd;
406
407   get_ps_stuff(proc_fd, this->argv0, this->pathenv, this->cwdenv);
408
409   return true;
410 }
411
412 bool process::isRunning_() const {
413    // determine if a process is running by doing low-level system checks, as
414    // opposed to checking the 'status_' member vrble.  May assume that attach()
415    // has run, but can't assume anything else.
416    prstatus theStatus;
417    if (-1 == ioctl(proc_fd, PIOCSTATUS, &theStatus)) {
418       perror("process::isRunning_()");
419       assert(false);
420    }
421
422    if (theStatus.pr_flags & PR_STOPPED)
423       return false;
424    else
425       return true;
426 }
427
428 bool process::attach_() {assert(false);}
429 bool process::stop_() {assert(false);}
430
431 /* 
432    continue a process that is stopped 
433 */
434 bool process::continueProc_() {
435   ptraceOps++; ptraceOtherOps++;
436   prrun_t flags;
437   prstatus_t stat;
438
439 //cerr << "welcome to continueProc_()" << endl;
440
441   // a process that receives a stop signal stops twice. We need to run the process
442   // and wait for the second stop. (The first run simply absorbs the stop signal;
443   // the second one does the actual continue.)
444   if ((ioctl(proc_fd, PIOCSTATUS, &stat) != -1)
445       && (stat.pr_flags & PR_STOPPED)
446       && (stat.pr_why == PR_SIGNALLED)
447       && (stat.pr_what == SIGSTOP || stat.pr_what == SIGINT)) {
448     flags.pr_flags = PRSTOP;
449     if (ioctl(proc_fd, PIOCRUN, &flags) == -1) {
450       fprintf(stderr, "continueProc_: PIOCRUN failed: %s\n", sys_errlist[errno]);
451       return false;
452     }
453     if (ioctl(proc_fd, PIOCWSTOP, 0) == -1) {
454       fprintf(stderr, "continueProc_: PIOCWSTOP failed: %s\n", sys_errlist[errno]);
455       return false;
456     }
457   }
458   flags.pr_flags = PRCSIG; // clear current signal
459   if (hasNewPC) {
460     // set new program counter
461     //cerr << "continueProc_ doing new currentPC: " << (void*)currentPC_ << endl;
462     flags.pr_vaddr = (caddr_t) currentPC_;
463     flags.pr_flags |= PRSVADDR;
464     hasNewPC = false;
465   }
466   if (ioctl(proc_fd, PIOCRUN, &flags) == -1) {
467     fprintf(stderr, "continueProc_: PIOCRUN 2 failed: %s\n", sys_errlist[errno]);
468     return false;
469   }
470
471   return true;
472 }
473
474 #ifdef BPATCH_LIBRARY
475 /*
476    terminate execution of a process
477  */
478 bool process::terminateProc_()
479 {
480     int sig = SIGKILL;
481     if (ioctl(proc_fd, PIOCKILL, &sig) == -1)
482         return false;
483     else
484         return true;
485 }
486 #endif
487
488 /*
489    pause a process that is running
490 */
491 bool process::pause_() {
492   ptraceOps++; ptraceOtherOps++;
493
494   // /proc PIOCSTOP: direct all LWPs to stop, _and_ wait for them to stop.
495   return (ioctl(proc_fd, PIOCSTOP, 0) != -1);
496 }
497
498 /*
499    close the file descriptor for the file associated with a process
500 */
501 bool process::detach_() {
502   close(proc_fd);
503   return true;
504 }
505
506 #ifdef BPATCH_LIBRARY
507 /*
508    detach from thr process, continuing its execution if the parameter "cont"
509    is true.
510  */
511 bool process::API_detach_(const bool cont)
512 {
513   // Reset the kill-on-close flag, and the run-on-last-close flag if necessary
514   long flags = PR_KLC;
515   if (!cont) flags |= PR_RLC;
516   if (ioctl (proc_fd, PIOCRESET, &flags) < 0) {
517     fprintf(stderr, "detach: PIOCRESET failed: %s\n", sys_errlist[errno]);
518     close(proc_fd);
519     return false;
520   }
521   // Set the run-on-last-close-flag if necessary
522   if (cont) {
523     flags = PR_RLC;
524     if (ioctl (proc_fd, PIOCSET, &flags) < 0) {
525       fprintf(stderr, "detach: PIOCSET failed: %s\n", sys_errlist[errno]);
526       close(proc_fd);
527       return false;
528     }
529   }
530
531   sigset_t sigs;
532   premptyset(&sigs);
533   if (ioctl(proc_fd, PIOCSTRACE, &sigs) < 0) {
534     fprintf(stderr, "detach: PIOCSTRACE failed: %s\n", sys_errlist[errno]);
535     close(proc_fd);
536     return false;
537   }
538   if (ioctl(proc_fd, PIOCSHOLD, &sigs) < 0) {
539     fprintf(stderr, "detach: PIOCSHOLD failed: %s\n", sys_errlist[errno]);
540     close(proc_fd);
541     return false;
542   }
543
544   fltset_t faults;
545   premptyset(&faults);
546   if (ioctl(proc_fd, PIOCSFAULT, &faults) < 0) {
547     fprintf(stderr, "detach: PIOCSFAULT failed: %s\n", sys_errlist[errno]);
548     close(proc_fd);
549     return false;
550   }
551   
552   sysset_t syscalls;
553   premptyset(&syscalls);
554   if (ioctl(proc_fd, PIOCSENTRY, &syscalls) < 0) {
555     fprintf(stderr, "detach: PIOCSENTRY failed: %s\n", sys_errlist[errno]);
556     close(proc_fd);
557     return false;
558   }
559   if (ioctl(proc_fd, PIOCSEXIT, &syscalls) < 0) {
560     fprintf(stderr, "detach: PIOCSEXIT failed: %s\n", sys_errlist[errno]);
561     close(proc_fd);
562     return false;
563   }
564
565   close(proc_fd);
566   return true;
567 }
568 #endif
569
570 bool process::dumpCore_(const string) {
571   return false;
572 }
573
574 bool process::writeTextWord_(caddr_t inTraced, int data) {
575 //  cerr << "writeTextWord @ " << (void *)inTraced << endl; cerr.flush();
576   return writeDataSpace_(inTraced, sizeof(int), (caddr_t) &data);
577 }
578
579 bool process::writeTextSpace_(void *inTraced, int amount, const void *inSelf) {
580 //  cerr << "writeTextSpace pid=" << getPid() << ", @ " << (void *)inTraced << " len=" << amount << endl; cerr.flush();
581   return writeDataSpace_(inTraced, amount, inSelf);
582 }
583
584 #ifdef BPATCH_SET_MUTATIONS_ACTIVE
585 bool process::readTextSpace_(void *inTraced, int amount, const void *inSelf) {
586   return readDataSpace_(inTraced, amount, inSelf);
587 }
588 #endif
589
590 bool process::writeDataSpace_(void *inTraced, int amount, const void *inSelf) {
591   ptraceOps++; ptraceBytes += amount;
592
593 //  cerr << "process::writeDataSpace_ pid " << getPid() << " writing " << amount << " bytes at loc " << inTraced << endl;
594
595   if (lseek(proc_fd, (off_t)inTraced, SEEK_SET) != (off_t)inTraced)
596     return false;
597   return (write(proc_fd, inSelf, amount) == amount);
598 }
599
600 bool process::readDataSpace_(const void *inTraced, int amount, void *inSelf) {
601   ptraceOps++; ptraceBytes += amount;
602   if((lseek(proc_fd, (off_t)inTraced, SEEK_SET)) != (off_t)inTraced) {
603     printf("error in lseek addr = 0x%x amount = %d\n",(u_int)inTraced,amount);
604     return false;
605   }
606   return (read(proc_fd, inSelf, amount) == amount);
607 }
608
609 bool process::loopUntilStopped() {
610   assert(0);
611 }
612
613 #ifdef notdef
614 // TODO -- only call getrusage once per round
615 static struct rusage *get_usage_data() {
616   return NULL;
617 }
618 #endif
619
620 float OS::compute_rusage_cpu() {
621   return 0;
622 }
623
624 float OS::compute_rusage_sys() {
625   return 0;
626 }
627
628 float OS::compute_rusage_min() {
629   return 0;
630 }
631 float OS::compute_rusage_maj() {
632   return 0;
633 }
634
635 float OS::compute_rusage_swap() {
636   return 0;
637 }
638 float OS::compute_rusage_io_in() {
639   return 0;
640 }
641 float OS::compute_rusage_io_out() {
642   return 0;
643 }
644 float OS::compute_rusage_msg_send() {
645   return 0;
646 }
647 float OS::compute_rusage_msg_recv() {
648   return 0;
649 }
650 float OS::compute_rusage_sigs() {
651   return 0;
652 }
653 float OS::compute_rusage_vol_cs() {
654   return 0;
655 }
656 float OS::compute_rusage_inv_cs() {
657   return 0;
658 }
659
660 int getNumberOfCPUs()
661 {
662   // _SC_NPROCESSORS_CONF is the number of processors configured in the
663   // system and _SC_NPROCESSORS_ONLN is the number of those processors that
664   // are online.
665   int numberOfCPUs;
666   numberOfCPUs = (int) sysconf(_SC_NPROCESSORS_ONLN);
667   if (numberOfCPUs) 
668     return(numberOfCPUs);
669   else 
670     return(1);
671 }  
672
673
674 bool process::getActiveFrame(int *fp, int *pc)
675 {
676   prgregset_t regs;
677   bool ok=false;
678
679   if (ioctl (proc_fd, PIOCGREG, &regs) != -1) {
680       *fp=regs[FP_REG];
681       *pc=regs[PC_REG];
682       ok=true;
683   }
684   return(ok);
685 }
686
687 #ifdef sparc_sun_solaris2_4
688
689 bool process::readDataFromFrame(int currentFP, int *fp, int *rtn, bool uppermost)
690 {
691   bool readOK=true;
692   struct {
693     int fp;
694     int rtn;
695   } addrs;
696
697   prgregset_t regs;
698   function_base *func;
699   int pc = *rtn;
700
701   if (uppermost) {
702       func = this->findFunctionIn(pc);
703       if (func) {
704          if (func->hasNoStackFrame()) { // formerly "isLeafFunc()"
705               if (ioctl (proc_fd, PIOCGREG, &regs) != -1) {
706                   *rtn = regs[R_O7] + 8;
707                   return readOK;
708               }    
709          }
710       }
711   }
712
713   //
714   // For the sparc, register %i7 is the return address - 8 and the fp is
715   // register %i6. These registers can be located in currentFP+14*5 and
716   // currentFP+14*4 respectively, but to avoid two calls to readDataSpace,
717   // we bring both together (i.e. 8 bytes of memory starting at currentFP+14*4
718   // or currentFP+56).
719   // These values are copied to the stack when the application is paused,
720   // so we are assuming that the application is paused at this point
721
722   if (readDataSpace((caddr_t) (currentFP + 56),
723                     sizeof(int)*2, (caddr_t) &addrs, true)) {
724     // this is the previous frame pointer
725     *fp = addrs.fp;
726     // return address
727     *rtn = addrs.rtn + 8;
728
729     // if pc==0, then we are in the outermost frame and we should stop. We
730     // do this by making fp=0.
731
732     if ( (addrs.rtn == 0) || !isValidAddress(this,(Address) addrs.rtn) ) {
733       readOK=false;
734     }
735   }
736   else {
737     readOK=false;
738   }
739
740
741   return(readOK);
742 }
743
744 #endif
745
746 #ifdef SHM_SAMPLING
747 time64 process::getInferiorProcessCPUtime() {
748    // returns user+sys time from the u or proc area of the inferior process, which in
749    // turn is presumably obtained by mmapping it (sunos) or by using a /proc ioctl
750    // to obtain it (solaris).  It must not stop the inferior process in order
751    // to obtain the result, nor can it assue that the inferior has been stopped.
752    // The result MUST be "in sync" with rtinst's DYNINSTgetCPUtime().
753
754    // We use the PIOCUSAGE /proc ioctl
755
756    // Other /proc ioctls that should work too: PIOCPSINFO
757    // and the lower-level PIOCGETPR and PIOCGETU which return copies of the proc
758    // and u areas, respectively.
759    // PIOCSTATUS does _not_ work because its results are not in sync
760    // with DYNINSTgetCPUtime
761
762    time64 result;
763    prpsinfo_t theUsage;
764
765    if (ioctl(proc_fd, PIOCPSINFO, &theUsage) == -1) {
766       perror("could not read CPU time of inferior PIOCPSINFO");
767       return 0;
768    }
769    result = PDYN_mulMillion(theUsage.pr_time.tv_sec); // sec to usec
770    result += PDYN_div1000(theUsage.pr_time.tv_nsec);  // nsec to usec
771
772    if (result<previous) {
773      // time shouldn't go backwards, but we have seen this happening
774      // before, so we better check it just in case - naim 5/30/97
775      logLine("********* time going backwards in paradynd **********\n");
776      result=previous;
777    } else {
778      previous=result;
779    }
780
781    return result;
782 }
783 #endif
784
785 void *process::getRegisters() {
786    // Astonishingly, this routine can be shared between solaris/sparc and
787    // solaris/x86.  All hail /proc!!!
788
789    // assumes the process is stopped (/proc requires it)
790    assert(status_ == stopped);
791
792    prgregset_t theIntRegs;
793    if (ioctl(proc_fd, PIOCGREG, &theIntRegs) == -1) {
794       perror("process::getRegisters PIOCGREG");
795       if (errno == EBUSY) {
796          cerr << "It appears that the process was not stopped in the eyes of /proc" << endl;
797          assert(false);
798       }
799
800       return NULL;
801    }
802
803    prfpregset_t theFpRegs;
804    if (ioctl(proc_fd, PIOCGFPREG, &theFpRegs) == -1) {
805       perror("process::getRegisters PIOCGFPREG");
806       if (errno == EBUSY)
807          cerr << "It appears that the process was not stopped in the eyes of /proc" << endl;
808       else if (errno == EINVAL)
809          // what to do in this case?  Probably shouldn't even do a print, right?
810          // And it certainly shouldn't be an error, right?
811          // But I wonder if any sparcs out there really don't have floating point.
812          cerr << "It appears that this machine doesn't have floating-point instructions" << endl;
813
814       return NULL;
815    }
816
817    const int numbytesPart1 = sizeof(prgregset_t);
818    const int numbytesPart2 = sizeof(prfpregset_t);
819    assert(numbytesPart1 % 4 == 0);
820    assert(numbytesPart2 % 4 == 0);
821
822    void *buffer = new char[numbytesPart1 + numbytesPart2];
823    assert(buffer);
824
825    memcpy(buffer, &theIntRegs, sizeof(theIntRegs));
826    memcpy((char *)buffer + sizeof(theIntRegs), &theFpRegs, sizeof(theFpRegs));
827
828    return buffer;
829 }
830
831 bool process::executingSystemCall() {
832    prstatus theStatus;
833    if (ioctl(proc_fd, PIOCSTATUS, &theStatus) != -1) {
834      if (theStatus.pr_syscall > 0) {
835        inferiorrpc_cerr << "pr_syscall=" << theStatus.pr_syscall << endl;
836        return(true);
837      }
838    } else assert(0);
839    return(false);
840 }
841
842 bool process::changePC(unsigned addr, const void *savedRegs) {
843    assert(status_ == stopped);
844
845    prgregset_t theIntRegs = *(const prgregset_t *)savedRegs; // makes a copy, on purpose
846
847    theIntRegs[R_PC] = addr; // PC (sparc), EIP (x86)
848 #ifdef R_nPC  // true for sparc, not for x86
849    theIntRegs[R_nPC] = addr + 4;
850 #endif
851
852    if (ioctl(proc_fd, PIOCSREG, &theIntRegs) == -1) {
853       perror("process::changePC PIOCSREG failed");
854       if (errno == EBUSY)
855          cerr << "It appears that the process wasn't stopped in the eyes of /proc" << endl;
856       return false;
857    }
858
859    return true;
860 }
861
862 bool process::changePC(unsigned addr) {
863    assert(status_ == stopped); // /proc will require this
864
865    prgregset_t theIntRegs;
866    if (-1 == ioctl(proc_fd, PIOCGREG, &theIntRegs)) {
867       perror("process::changePC PIOCGREG");
868       if (errno == EBUSY) {
869          cerr << "It appears that the process wasn't stopped in the eyes of /proc" << endl;
870          assert(false);
871       }
872       return false;
873    }
874
875    theIntRegs[R_PC] = addr;
876 #ifdef R_nPC
877    theIntRegs[R_nPC] = addr + 4;
878 #endif
879
880    if (-1 == ioctl(proc_fd, PIOCSREG, &theIntRegs)) {
881       perror("process::changePC PIOCSREG");
882       if (errno == EBUSY) {
883          cerr << "It appears that the process wasn't stopped in the eyes of /proc" << endl;
884          assert(false);
885       }
886       return false;
887    }
888
889    return true;
890 }
891
892 bool process::restoreRegisters(void *buffer) {
893    // The fact that this routine can be shared between solaris/sparc and
894    // solaris/x86 is just really, really cool.  /proc rules!
895
896    assert(status_ == stopped); // /proc requires it
897
898    prgregset_t theIntRegs = *(prgregset_t *)buffer;
899    prfpregset_t theFpRegs = *(prfpregset_t *)((char *)buffer + sizeof(theIntRegs));
900
901    if (ioctl(proc_fd, PIOCSREG, &theIntRegs) == -1) {
902       perror("process::restoreRegisters PIOCSREG failed");
903       if (errno == EBUSY) {
904          cerr << "It appears that the process was not stopped in the eyes of /proc" << endl;
905          assert(false);
906       }
907       return false;
908    }
909
910    if (ioctl(proc_fd, PIOCSFPREG, &theFpRegs) == -1) {
911       perror("process::restoreRegisters PIOCSFPREG failed");
912       if (errno == EBUSY) {
913          cerr << "It appears that the process was not stopped in the eyes of /proc" << endl;
914          assert(false);
915       }
916       return false;
917    }
918
919    return true;
920 }
921
922 #ifdef i386_unknown_solaris2_5
923
924 bool process::readDataFromFrame(int currentFP, int *fp, int *rtn, bool )
925 {
926   bool readOK=true;
927   struct {
928     int fp;
929     int rtn;
930   } addrs;
931
932   //
933   // for the x86, the frame-pointer (EBP) points to the previous frame-pointer,
934   // and the saved return address is in EBP-4.
935   //
936
937   if (readDataSpace((caddr_t) (currentFP),
938                     sizeof(int)*2, (caddr_t) &addrs, true)) {
939     // this is the previous frame pointer
940     *fp = addrs.fp;
941     // return address
942     *rtn = addrs.rtn;
943
944     // if pc==0, then we are in the outermost frame and we should stop. We
945     // do this by making fp=0.
946
947     if ( (addrs.rtn == 0) || !isValidAddress(this,(Address) addrs.rtn) ) {
948       readOK=false;
949     }
950   }
951   else {
952     readOK=false;
953   }
954
955   return(readOK);
956 }
957
958 #endif
959
960 #ifdef i386_unknown_solaris2_5
961 // ******** TODO **********
962 bool process::needToAddALeafFrame(Frame , Address &) {
963   return false;
964 }
965
966 #else
967
968 // needToAddALeafFrame: returns true if the between the current frame 
969 // and the next frame there is a leaf function (this occurs when the 
970 // current frame is the signal handler and the function that was executing
971 // when the sighandler was called is a leaf function)
972 bool process::needToAddALeafFrame(Frame current_frame, Address &leaf_pc){
973
974    // check to see if the current frame is the signal handler 
975    Address frame_pc = current_frame.getPC();
976    Address sig_addr = 0;
977    const image *sig_image = (signal_handler->file())->exec();
978    if(getBaseAddress(sig_image, sig_addr)){
979        sig_addr += signal_handler->getAddress(0);
980    } else {
981        sig_addr = signal_handler->getAddress(0);
982    }
983    u_int sig_size = signal_handler->size();
984    if(signal_handler&&(frame_pc >= sig_addr)&&(frame_pc < (sig_addr+sig_size))){
985        // get the value of the saved PC: this value is stored in the address
986        // specified by the value in register i2 + 44. Register i2 must contain
987        // the address of some struct that contains, among other things, the 
988        // saved PC value.  
989        u_int reg_i2;
990        int fp = current_frame.getFramePtr();
991        if (readDataSpace((caddr_t)(fp+40),sizeof(u_int),(caddr_t)&reg_i2,true)){
992           if (readDataSpace((caddr_t) (reg_i2+44), sizeof(int),
993                             (caddr_t) &leaf_pc,true)){
994               // if the function is a leaf function return true
995               function_base *func = findFunctionIn(leaf_pc);
996               if(func && func->hasNoStackFrame()) { // formerly "isLeafFunc()"
997                   return(true);
998               }
999           }
1000       }
1001    }
1002    return false;
1003 }
1004 #endif
1005
1006 string process::tryToFindExecutable(const string &iprogpath, int pid) {
1007    // returns empty string on failure.
1008    // Otherwise, returns a full-path-name for the file.  Tries every
1009    // trick to determine the full-path-name, even though "progpath" may be
1010    // unspecified (empty string).
1011    
1012    // Remember, we can always return the empty string...no need to
1013    // go nuts writing the world's most complex algorithm.
1014
1015    attach_cerr << "welcome to tryToFindExecutable; progpath=" << iprogpath << ", pid=" << pid << endl;
1016
1017    const string progpath = expand_tilde_pathname(iprogpath);
1018
1019    // Trivial case: if "progpath" is specified and the file exists then nothing needed
1020    if (exists_executable(progpath)) {
1021       attach_cerr << "tryToFindExecutable succeeded immediately, returning "
1022                   << progpath << endl;
1023       return progpath;
1024    }
1025
1026    attach_cerr << "tryToFindExecutable failed on filename " << progpath << endl;
1027
1028    char buffer[128];
1029    sprintf(buffer, "/proc/%05d", pid);
1030    int procfd = open(buffer, O_RDONLY, 0);
1031    if (procfd == -1) {
1032       attach_cerr << "tryToFindExecutable failed since open of /proc failed" << endl;
1033       return "";
1034    }
1035    attach_cerr << "tryToFindExecutable: opened /proc okay" << endl;
1036
1037    string argv0, path, cwd;
1038    get_ps_stuff(procfd, argv0, path, cwd);
1039
1040    // the following routine is implemented in the util lib.
1041    string result;
1042    if (executableFromArgv0AndPathAndCwd(result, argv0, path, cwd)) {
1043       (void)close(procfd);
1044       return result;
1045    }
1046
1047    attach_cerr << "tryToFindExecutable: giving up" << endl;
1048
1049    (void)close(procfd);
1050    return "";
1051 }
1052
1053 bool process::set_breakpoint_for_syscall_completion() {
1054    /* Can assume: (1) process is paused and (2) in a system call.
1055       We want to set a TRAP for the syscall exit, and do the
1056       inferiorRPC at that time.  We'll use /proc PIOCSEXIT.
1057       Returns true iff breakpoint was successfully set. */
1058
1059    sysset_t save_exitset;
1060    if (-1 == ioctl(proc_fd, PIOCGEXIT, &save_exitset))
1061       return false;
1062
1063    sysset_t new_exit_set;
1064    prfillset(&new_exit_set);
1065    if (-1 == ioctl(proc_fd, PIOCSEXIT, &new_exit_set))
1066       return false;
1067
1068    assert(save_exitset_ptr == NULL);
1069    save_exitset_ptr = new sysset_t;
1070    memcpy(save_exitset_ptr, &save_exitset, sizeof(save_exitset));
1071
1072    return true;
1073 }
1074
1075 unsigned process::read_inferiorRPC_result_register(reg) {
1076    prgregset_t theIntRegs;
1077    if (-1 == ioctl(proc_fd, PIOCGREG, &theIntRegs)) {
1078       perror("process::read_inferiorRPC_result_register PIOCGREG");
1079       if (errno == EBUSY) {
1080          cerr << "It appears that the process was not stopped in the eyes of /proc" << endl;
1081          assert(false);
1082       }
1083       return 0; // assert(false)?
1084    }
1085
1086    // on x86, the result is always stashed in %EAX; on sparc, it's always %o0.  In
1087    // neither case do we need the argument of this fn.
1088 #ifdef i386_unknown_solaris2_5
1089    return theIntRegs[EAX];
1090 #else
1091    return theIntRegs[R_O0];
1092 #endif
1093 }
1094
1095 // hasBeenBound: returns true if the runtime linker has bound the
1096 // function symbol corresponding to the relocation entry in at the address
1097 // specified by entry and base_addr.  If it has been bound, then the callee 
1098 // function is returned in "target_pdf", else it returns false.
1099 bool process::hasBeenBound(const relocationEntry entry, 
1100                            pd_Function *&target_pdf, Address base_addr) {
1101
1102 // TODO: the x86 and sparc versions should really go in seperate files 
1103 #if defined(i386_unknown_solaris2_5)
1104
1105     // if the relocationEntry has not been bound yet, then the value
1106     // at rel_addr is the address of the instruction immediately following
1107     // the first instruction in the PLT entry (which is at the target_addr) 
1108     // The PLT entries are never modified, instead they use an indirrect 
1109     // jump to an address stored in the _GLOBAL_OFFSET_TABLE_.  When the 
1110     // function symbol is bound by the runtime linker, it changes the address
1111     // in the _GLOBAL_OFFSET_TABLE_ corresponding to the PLT entry
1112
1113     Address got_entry = entry.rel_addr() + base_addr;
1114     Address bound_addr = 0;
1115     if(!readDataSpace((const void*)got_entry, sizeof(Address), 
1116                         &bound_addr, true)){
1117         sprintf(errorLine, "read error in process::hasBeenBound addr 0x%x\n",
1118                 got_entry);
1119         logLine(errorLine);
1120         return false;
1121     }
1122
1123     if( !( bound_addr == (entry.target_addr()+6+base_addr)) ) {
1124         // the callee function has been bound by the runtime linker
1125         // find the function and return it
1126         target_pdf = findpdFunctionIn(bound_addr);
1127         if(!target_pdf){
1128             return false;
1129         }
1130         return true;    
1131     }
1132     return false;
1133
1134 #else
1135     // if the relocationEntry has not been bound yet, then the second instr 
1136     // in this PLT entry branches to the fist PLT entry.  If it has been   
1137     // bound, then second two instructions of the PLT entry have been changed 
1138     // by the runtime linker to jump to the address of the function.  
1139     // Here is an example:   
1140     //     before binding                       after binding
1141     //     --------------                       -------------
1142     //     sethi  %hi(0x15000), %g1             sethi  %hi(0x15000), %g1
1143     //     b,a  <_PROCEDURE_LINKAGE_TABLE_>     sethi  %hi(0xef5eb000), %g1
1144     //     nop                                  jmp  %g1 + 0xbc ! 0xef5eb0bc
1145
1146     instruction next_insn;
1147     Address next_insn_addr = entry.target_addr() + base_addr + 4; 
1148     if( !(readDataSpace((caddr_t)next_insn_addr, sizeof(next_insn), 
1149                        (char *)&next_insn, true)) ) {
1150         sprintf(errorLine, "read error in process::hasBeenBound addr 0x%x\n",
1151                 next_insn_addr);
1152         logLine(errorLine);
1153     }
1154     // if this is a b,a instruction, then the function has not been bound
1155     if((next_insn.branch.op == FMT2op)  && (next_insn.branch.op2 == BICCop2) 
1156        && (next_insn.branch.anneal == 1) && (next_insn.branch.cond == BAcond)) {
1157         return false;
1158     } 
1159
1160     // if this is a sethi instruction, then it has been bound...get target_addr
1161     instruction third_insn;
1162     Address third_addr = entry.target_addr() + base_addr + 8; 
1163     if( !(readDataSpace((caddr_t)third_addr, sizeof(third_insn), 
1164                        (char *)&third_insn, true)) ) {
1165         sprintf(errorLine, "read error in process::hasBeenBound addr 0x%x\n",
1166                 third_addr);
1167         logLine(errorLine);
1168     }
1169
1170     // get address of bound function, and return the corr. pd_Function
1171     if((next_insn.sethi.op == FMT2op) && (next_insn.sethi.op2 == SETHIop2)
1172         && (third_insn.rest.op == RESTop) && (third_insn.rest.i == 1)
1173         && (third_insn.rest.op3 == JMPLop3)) {
1174         
1175         Address new_target = (next_insn.sethi.imm22 << 10) & 0xfffffc00; 
1176         new_target |= third_insn.resti.simm13;
1177
1178         target_pdf = findpdFunctionIn(new_target);
1179         if(!target_pdf){
1180             return false;
1181         }
1182         return true;
1183     }
1184     // this is a messed up entry
1185     return false;
1186 #endif
1187
1188 }
1189
1190
1191
1192 // findCallee: finds the function called by the instruction corresponding
1193 // to the instPoint "instr". If the function call has been bound to an
1194 // address, then the callee function is returned in "target" and the 
1195 // instPoint "callee" data member is set to pt to callee's function_base.  
1196 // If the function has not yet been bound, then "target" is set to the 
1197 // function_base associated with the name of the target function (this is 
1198 // obtained by the PLT and relocation entries in the image), and the instPoint
1199 // callee is not set.  If the callee function cannot be found, (ex. function
1200 // pointers, or other indirect calls), it returns false.
1201 // Returns false on error (ex. process doesn't contain this instPoint).
1202 //
1203 // The assumption here is that for all processes sharing the image containing
1204 // this instPoint they are going to bind the call target to the same function. 
1205 // For shared objects this is always true, however this may not be true for
1206 // dynamic executables.  Two a.outs can be identical except for how they are
1207 // linked, so a call to fuction foo in one version of the a.out may be bound
1208 // to function foo in libfoo.so.1, and in the other version it may be bound to 
1209 // function foo in libfoo.so.2.  We are currently not handling this case, since
1210 // it is unlikely to happen in practice.
1211 bool process::findCallee(instPoint &instr, function_base *&target){
1212     
1213     if((target = (function_base *)instr.iPgetCallee())) {
1214         return true; // callee already set
1215     }
1216
1217     // find the corresponding image in this process  
1218     const image *owner = instr.iPgetOwner();
1219     bool found_image = false;
1220     Address base_addr = 0;
1221     if(symbols == owner) {  found_image = true; } 
1222     else if(shared_objects){
1223         for(u_int i=0; i < shared_objects->size(); i++){
1224             if(owner == ((*shared_objects)[i])->getImage()) {
1225                 found_image = true;
1226                 base_addr = ((*shared_objects)[i])->getBaseAddress();
1227                 break;
1228             }
1229         }
1230     } 
1231     if(!found_image) {
1232         target = 0;
1233         return false; // image not found...this is bad
1234     }
1235
1236     // get the target address of this function
1237     Address target_addr = 0;
1238     Address insn_addr = instr.iPgetAddress(); 
1239     target_addr = instr.getTargetAddress();
1240
1241     if(!target_addr) {  
1242         // this is either not a call instruction or an indirect call instr
1243         // that we can't get the target address
1244         target = 0;
1245         return false;
1246     }
1247
1248 #if defined(sparc_sun_solaris2_4)
1249     // If this instPoint is from a function that was relocated to the heap
1250     // then need to get the target address relative to this image   
1251     if(target_addr && instr.relocated_) {
1252         assert(target_addr > base_addr);
1253         target_addr -= base_addr;
1254     }
1255 #endif
1256
1257     // see if there is a function in this image at this target address
1258     // if so return it
1259     pd_Function *pdf = 0;
1260     if( (pdf = owner->findFunctionIn(target_addr,this)) ) {
1261         target = pdf;
1262         instr.set_callee(pdf);
1263         return true; // target found...target is in this image
1264     }
1265
1266     // else, get the relocation information for this image
1267     const Object &obj = owner->getObject();
1268     vector<relocationEntry> fbt;
1269     if(!obj.get_func_binding_table(fbt)) {
1270         target = 0;
1271         return false; // target cannot be found...it is an indirect call.
1272     }
1273
1274     // find the target address in the list of relocationEntries
1275     for(u_int i=0; i < fbt.size(); i++) {
1276         if(fbt[i].target_addr() == target_addr) {
1277             // check to see if this function has been bound yet...if the
1278             // PLT entry for this function has been modified by the runtime
1279             // linker
1280             pd_Function *target_pdf = 0;
1281             if(hasBeenBound(fbt[i], target_pdf, base_addr)) {
1282                 target = target_pdf;
1283                 instr.set_callee(target_pdf);
1284                 return true;  // target has been bound
1285             } 
1286             else {
1287                 // just try to find a function with the same name as entry 
1288                 target = findOneFunctionFromAll(fbt[i].name());
1289                 if(target){
1290                     return true;
1291                 }
1292                 else {  
1293                     // KLUDGE: this is because we are not keeping more than
1294                     // one name for the same function if there is more
1295                     // than one.  This occurs when there are weak symbols
1296                     // that alias global symbols (ex. libm.so.1: "sin" 
1297                     // and "__sin").  In most cases the alias is the same as 
1298                     // the global symbol minus one or two leading underscores,
1299                     // so here we add one or two leading underscores to search
1300                     // for the name to handle the case where this string 
1301                     // is the name of the weak symbol...this will not fix 
1302                     // every case, since if the weak symbol and global symbol
1303                     // differ by more than leading underscores we won't find
1304                     // it...when we parse the image we should keep multiple
1305                     // names for pd_Functions
1306
1307                     string s = string("_");
1308                     s += fbt[i].name();
1309                     target = findOneFunctionFromAll(s);
1310                     if(target){
1311                         return true;
1312                     }
1313                     s = string("__");
1314                     s += fbt[i].name();
1315                     target = findOneFunctionFromAll(s);
1316                     if(target){
1317                         return true;
1318                     }
1319                 }
1320             }
1321             target = 0;
1322             return false;
1323         }
1324     }
1325     target = 0;
1326     return false;  
1327 }