BPatch functions that block are now locked (on a finer grain than the rest of the...
[dyninst.git] / dyninstAPI / src / sol_proc.C
1 /*
2  * Copyright (c) 1996-2004 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 // Solaris-style /proc support
43
44 // $Id: sol_proc.C,v 1.58 2005/02/25 07:04:47 jaw Exp $
45
46 #ifdef AIX_PROC
47 #include <sys/procfs.h>
48 #else
49 #include <procfs.h>
50 #endif
51 #include <limits.h>
52 #include <poll.h>
53 #include <sys/types.h>  // for reading lwps out of proc
54 #include <dirent.h>     // for reading lwps out of proc
55 #include "common/h/headers.h"
56 #include "dyninstAPI/src/signalhandler.h"
57 #include "dyninstAPI/src/process.h"
58 #include "dyninstAPI/src/dyn_lwp.h"
59 #include "dyninstAPI/src/dyn_thread.h"
60 #include "dyninstAPI/src/stats.h"
61 #include "common/h/pathName.h" // for path name manipulation routines
62 #include "dyninstAPI/src/sol_proc.h"
63
64 /*
65    osTraceMe is called after we fork a child process to set
66    a breakpoint on the exit of the exec system call.
67    When /proc is used, this breakpoint **will not** cause a SIGTRAP to 
68    be sent to the process. The parent should use PIOCWSTOP to wait for 
69    the child.
70 */
71 // Interesting problem: I've seen a race condition occur when
72 // we set the proc trace flags from the mutator before the
73 // mutatee. In this case, DON'T reset the flags if there
74 // is a stop on exec in effect.
75
76 void OS::osTraceMe(void) {
77     sysset_t *exitSet = SYSSET_ALLOC(getpid());
78     int bufsize = SYSSET_SIZE(exitSet) + sizeof(long);
79
80     char *buf = new char[bufsize];
81     long *bufptr = (long *)buf;
82     char procName[128];
83     
84     // Get the current set of syscalls
85     pstatus_t status;
86     sprintf(procName,"/proc/%d/status", (int) getpid());
87     int stat_fd = P_open(procName, O_RDONLY, 0);
88     if (pread(stat_fd, (void *)&status, sizeof(pstatus_t), 0) !=
89         sizeof(pstatus_t)) {
90         perror("osTraceMe::pread");
91         delete [] buf;
92         return;
93     }
94 #if defined(AIX_PROC) 
95     if (status.pr_sysexit_offset)
96         pread(stat_fd, exitSet, SYSSET_SIZE(exitSet), status.pr_sysexit_offset);
97     else // No syscalls are being traced 
98         premptysysset(exitSet);
99 #else
100     memcpy(exitSet, &(status.pr_sysexit), SYSSET_SIZE(exitSet));
101 #endif
102     close(stat_fd);
103
104     sprintf(procName,"/proc/%d/ctl", (int) getpid());
105     int fd = P_open(procName, O_WRONLY, 0);
106     if (fd < 0) {
107         perror("open");
108         delete [] buf;
109         return;
110     }
111     
112     /* set a breakpoint at the exit of exec/execve */
113     if (SYSSET_MAP(SYS_exec, getpid()) != -1) {
114         praddsysset(exitSet, SYSSET_MAP(SYS_exec, getpid()));
115     }
116     if (SYSSET_MAP(SYS_execve, getpid()) != -1) {
117         praddsysset(exitSet, SYSSET_MAP(SYS_execve, getpid()));
118     }
119     // Write out the command
120     *bufptr = PCSEXIT; bufptr++;
121     memcpy(bufptr, exitSet, SYSSET_SIZE(exitSet));
122     if (write(fd, buf, bufsize) != bufsize) {
123         perror("osTraceMe: PCSEXIT");
124         P__exit(-1); // must use _exit here.
125     }
126     
127
128     // AIX: do not close file descriptor or all changes are undone (?)
129     // My guess is we need to fiddle with the run on close/kill on 
130     // close bits. For now, leaving the FD open works.
131     //close(fd);    
132
133     delete [] buf;
134 }
135 /*
136  * DYN_LWP class
137  * Operations on LWP file descriptors, or the representative LWP
138  */
139
140 // determine if a process is running by doing low-level system checks, as
141 // opposed to checking the 'status_' member vrble.  May assume that attach()
142 // has run, but can't assume anything else.
143
144 bool dyn_lwp::isRunning() const {
145    lwpstatus_t theStatus;
146    
147    if (!get_status(&theStatus)) return false;
148
149    // Don't consider PR_ASLEEP to be stopped
150    long stopped_flags = PR_STOPPED | PR_ISTOP;
151
152    if (theStatus.pr_flags & stopped_flags)
153       return false;
154    else
155        return true;
156
157    
158 }
159
160 bool dyn_lwp::clearSignal() {
161     long command[2];
162     command[0] = PCRUN; command[1] = PRSTOP | PRCSIG;
163     if (write(ctl_fd(), command, 2*sizeof(long)) != 2*sizeof(long)) {
164         perror("clearSignal: PCRUN");
165         return false;
166     }
167     command[0] = PCWSTOP;
168     
169     if (write(ctl_fd(), command, sizeof(long)) != sizeof(long)) {
170         perror("clearSignal: PCWSTOP");
171         return false;
172     }
173     return true;
174 }
175
176 // Get the process running again. May do one or more of the following:
177 // 1) Continue twice to clear a signal
178 // 2) Restart an aborted system call
179 bool dyn_lwp::continueLWP_(int signalToContinueWith) {
180   lwpstatus_t status;
181   long command[2];
182   Address pc;  // PC at which we are trying to continue
183   // Check the current status
184   if (!get_status(&status)) {
185       bperr( "Failed to get LWP status\n");
186       return false;
187   }
188
189   if ((0==status.pr_flags & PR_STOPPED) && (0==status.pr_flags & PR_ISTOP)) {
190       bperr( "LWP not stopped\n");
191       return false;
192   }
193
194
195   // If the lwp is stopped on a signal we blip it (technical term).
196   // The process will re-stop (since we re-run with PRSTOP). At
197   // this point we continue it.
198   if ((status.pr_flags & PR_STOPPED)
199       && (status.pr_why == PR_SIGNALLED)) {
200       if (status.pr_what == SIGSTOP || 
201           status.pr_what == SIGINT ||
202           status.pr_what == SIGTRAP) {
203           clearSignal();
204       }
205   }
206
207   ptraceOps++; 
208   ptraceOtherOps++;
209
210
211   pc = (Address)(GETREG_PC(status.pr_reg));
212   if (stoppedInSyscall_ && pc == postsyscallpc_) {
213       if (!restartSyscall()) return false;
214   }
215   
216   command[0] = PCRUN;
217   if (signalToContinueWith == dyn_lwp::NoSignal)
218       command[1] = PRCSIG;  // clear the signal
219   else {
220       command[1] = 0;
221   }
222
223   // Continue the process the easy way
224   if (write(ctl_fd(), command, 2*sizeof(long)) != 2*sizeof(long)) {
225       perror("continueLWP: PCRUN2");
226       return false;
227   }
228   
229   return true;
230   
231 }
232
233 // Abort a system call. Place a trap at the exit of the syscall in
234 // question, and run with the ABORT flag set. Wait for the trap
235 // to be hit and then return.
236
237 bool dyn_lwp::abortSyscall()
238 {
239     lwpstatus_t status;
240
241     // MT: aborting syscalls does not work. Maybe someone with better knowledge
242     // of Solaris can get it working. 
243     if(proc_->multithread_capable(true))
244        return false;
245
246     // We do not expect to recursively interrupt system calls.  We could
247     // probably handle it by keeping a stack of system call state.  But
248     // we haven't yet seen any reason to have this functionality.
249     assert(!stoppedInSyscall_);
250     stoppedInSyscall_ = true;
251     
252     if (!get_status(&status)) return false;
253
254     if (status.pr_syscall == 0 ||
255         status.pr_why == PR_SYSEXIT) {
256         // No work to be done
257         stoppedInSyscall_ = false;
258         return true;
259     }
260
261     if (((status.pr_flags & PR_STOPPED) == 0) &&
262         ((status.pr_flags & PR_ISTOP) == 0))
263         stop_();
264     
265
266     sysset_t* scexit = SYSSET_ALLOC(proc_->getPid());
267     sysset_t* scsavedexit = SYSSET_ALLOC(proc_->getPid());
268     sysset_t* scentry = SYSSET_ALLOC(proc_->getPid());
269     sysset_t* scsavedentry = SYSSET_ALLOC(proc_->getPid());
270     
271     // 1. Save the syscall number, registers, and blocked signals
272     stoppedSyscall_ = status.pr_syscall;
273 /*
274     memcpy(&(syscallreg_->theIntRegs), &(status.pr_reg), sizeof(prgregset_t));
275     memcpy(&(syscallreg_->theFpRegs), &(status.pr_fpreg), sizeof(prfpregset_t));
276 */   
277  
278     memcpy(&sighold_, &status.pr_lwphold, sizeof(proc_sigset_t));
279     
280 #ifdef i386_unknown_solaris2_5
281     // From Roger A. Faulkner at Sun (email unknown), 6/29/1997:
282     //
283     // On Intel and PowerPC machines, the system call trap instruction
284     // leaves the PC (program counter, instruction pointer) referring to
285     // the instruction that follows the system call trap instruction.
286     // On Sparc machines, the system call trap instruction leaves %pc
287     // referring to the system call trap instruction itself (the
288     // operating system increments %pc on exit from the system call).
289     //
290     // We have to reset the PC back to the system call trap instruction
291     // on Intel and PowerPC machines.
292     //
293     // This is 7 on Intel, 4 on PowerPC.
294     
295     // Note: On x86/Linux this should probably be 2 bytes, because Linux
296     // uses "int" to trap, not lcall.
297     
298     syscallreg_.theIntRegs[PC_REG] -= 7;
299 #endif
300     
301     // 2. Abort the system call
302     
303     // Save current syscall exit traps
304     proc_->get_entry_syscalls(scsavedentry);
305     proc_->get_exit_syscalls(scsavedexit);
306     
307     // Set process to trap on exit from this system call
308     premptyset(scentry);
309     premptyset(scexit);
310     praddset(scexit, stoppedSyscall_);
311     
312     proc_->set_entry_syscalls(scentry);
313     proc_->set_exit_syscalls(scexit);
314     
315     // Continue, aborting this system call and blocking all sigs except
316     // those needed by DynInst.
317     proc_sigset_t sigs;
318     prfillset(&sigs);
319     prdelset(&sigs, SIGTRAP);
320     prdelset(&sigs, SIGILL);
321     
322     // Set the signals to "ignore" and run, aborting the syscall
323 #if 0
324     int bufsize = sizeof(long) + sizeof(proc_sigset_t);
325     char buf[bufsize]; long *bufptr = (long *)buf;
326     *bufptr = PCSHOLD; bufptr++;
327     memcpy(bufptr, &sigs, sizeof(proc_sigset_t));
328
329     if (write(ctl_fd(), buf, bufsize) != bufsize) {
330         perror("abortSyscall: PCSHOLD"); return false;
331     }
332 #endif
333     long command[2];
334     
335     command[0] = PCRUN;
336     command[1] = PRSABORT;
337
338     if (write(ctl_fd(), command, 2*sizeof(long)) != 2*sizeof(long)) {
339         perror("abortSyscall: PCRUN"); return false;
340     }
341     
342     command[0] = PCWSTOP;
343     if (write(ctl_fd(), command, sizeof(long)) != sizeof(long)) {
344         perror("abortSyscall: PCWSTOP"); return false;
345     }
346     
347     // Note: We assume that is always safe to restart the call after
348     // aborting it.  We are wrong if it turns out that some
349     // interruptible system call can make partial progress before we
350     // abort it.
351     // We think this is impossible because the proc manpage says EINTR
352     // would be returned to the process if we didn't trap the syscall
353     // exit, and the manpages for interruptible system calls say an
354     // EINTR return value means no progress was made.
355     // If we are wrong, this is probably the place to decide whether
356     // and/or how the syscall should be restarted later.
357     
358     if (!get_status(&status)) return false;
359     
360     // Verify that we're stopped in the right place
361     if (((status.pr_flags & (PR_STOPPED|PR_ISTOP))
362          != (PR_STOPPED|PR_ISTOP))
363         || status.pr_why != PR_SYSEXIT
364         || status.pr_syscall != stoppedSyscall_) {
365         sprintf(errorLine,
366                 "warn: Can't step paused process out of syscall (Verify)\n");
367         logLine(errorLine);
368         return 0;
369     }
370
371
372     // Get a copy of the registers and save for when we restart the syscall
373     // We ran the process, so clear the register cache
374     clearCachedRegister();
375     syscallreg_ = new dyn_saved_regs;
376     getRegisters(syscallreg_);
377     // And clear the cache again just to be safe
378     clearCachedRegister();
379     // Remember the current PC.  When we continue the process at this PC
380     // we will restart the system call.
381     postsyscallpc_ = (Address) GETREG_PC(syscallreg_->theIntRegs);
382     proc_->set_entry_syscalls(scsavedentry);
383     proc_->set_exit_syscalls(scsavedexit);
384     return true;
385 }
386
387 bool dyn_lwp::restartSyscall() {
388     if (!stoppedInSyscall_)
389         return true;
390     
391     // We interrupted a sleeping system call at some previous pause
392     // (i.e. stoppedInSyscall is true), we have not restarted that
393     // system call yet, and the current PC is the insn following
394     // the interrupted call.  It is time to restart the system
395     // call.
396     
397     // Note that when we make the process runnable, we ignore
398     // `flags', set if `hasNewPC' was true in the previous block,
399     // because we don't want its PC; we want the PC of the system
400     // call trap, which was saved in `syscallreg'.
401     if (!restoreRegisters(*syscallreg_)) return false;
402     delete syscallreg_;
403     syscallreg_ = NULL;
404     
405     // We are done -- the process is in the kernel for the system
406     // call, with the right registers values.  Make the process
407     // runnable, restoring its previously blocked signals.
408     // The signals were blocked as part of the abort mechanism.
409     stoppedInSyscall_ = false;
410 #if 0
411     int bufsize = sizeof(long) + sizeof(proc_sigset_t);
412     char buf[bufsize]; long *bufptr = (long *)buf;
413     *bufptr = PCSHOLD; bufptr++;
414     memcpy(bufptr, &sighold_, sizeof(proc_sigset_t));
415     
416     if (write(ctl_fd(), buf, bufsize) != bufsize) {
417         perror("continueLWP: PCSHOLD"); return false;
418     }
419 #endif
420     return true;
421 }
422
423
424
425 dyn_lwp *process::createRepresentativeLWP() {
426    // don't register the representativeLWP in the lwps since it's not a true
427    // lwp
428    representativeLWP = createFictionalLWP(0);
429    return representativeLWP;
430 }
431
432 // Stop the LWP in question
433 bool dyn_lwp::stop_() {
434   long command[2];
435   command[0] = PCSTOP;
436   if (write(ctl_fd(), command, sizeof(long)) != sizeof(long)) {
437       perror("pauseLWP: PCSTOP");
438       return false;
439   }
440
441   return true;
442 }
443
444 // Get the active frame (PC, FP/SP)
445 Frame dyn_lwp::getActiveFrame()
446 {
447    struct dyn_saved_regs regs;
448    bool status = getRegisters(&regs);
449    if(status == false)
450       return Frame();  
451
452    Frame newFrame = Frame(GETREG_PC(regs.theIntRegs),
453                           GETREG_FP(regs.theIntRegs), 
454                           0, // SP unused
455                           proc_->getPid(), proc_, NULL, this, true);
456    return newFrame;
457 }
458
459 // Get the registers of the stopped thread and return them.
460 bool dyn_lwp::getRegisters_(struct dyn_saved_regs *regs)
461 {
462     lwpstatus_t status;
463     if (!get_status(&status)) return false;
464
465     // Process must be stopped for register data to be correct.
466
467     assert((status.pr_flags & PR_STOPPED) || (status.pr_flags & PR_ISTOP)
468            || (status.pr_flags & PR_PCINVAL)  // eg. a trap at syscall exit
469            );
470
471     memcpy(&(regs->theIntRegs), &(status.pr_reg), sizeof(prgregset_t));
472     memcpy(&(regs->theFpRegs), &(status.pr_fpreg), sizeof(prfpregset_t));
473
474     return true;
475 }
476
477 void process::determineLWPs(pdvector<unsigned> *all_lwps) {
478    char procdir[128];
479    sprintf(procdir, "/proc/%d/lwp", getPid());
480    DIR *dirhandle = opendir(procdir);
481    struct dirent *direntry;
482    while((direntry= readdir(dirhandle)) != NULL) {
483       char str[100];
484       strncpy(str, direntry->d_name, direntry->d_reclen);
485       unsigned lwp_id = atoi(direntry->d_name);
486       if(lwp_id != 0) // && lwp_id != 1)
487          (*all_lwps).push_back(lwp_id);
488    }
489    closedir(dirhandle);
490 }
491
492 // Restore registers saved as above.
493 bool dyn_lwp::restoreRegisters_(const struct dyn_saved_regs &regs)
494 {
495     lwpstatus_t status;
496     get_status(&status);
497
498     // The fact that this routine can be shared between solaris/sparc and
499     // solaris/x86 is just really, really cool.  /proc rules!
500     const int regbufsize = sizeof(long) + sizeof(prgregset_t);
501     char regbuf[regbufsize]; long *regbufptr = (long *)regbuf;
502     *regbufptr = PCSREG; regbufptr++;
503     memcpy(regbufptr, &(regs.theIntRegs), sizeof(prgregset_t));
504     int writesize;
505     writesize = write(ctl_fd(), regbuf, regbufsize);
506     
507     if (writesize != regbufsize) {
508         perror("restoreRegisters: GPR write");
509         return false;
510     }
511     const int fpbufsize = sizeof(long) + sizeof(prfpregset_t);
512     char fpbuf[fpbufsize]; long *fpbufptr = (long *)fpbuf;
513     *fpbufptr = PCSFPREG; fpbufptr++;
514     memcpy(fpbufptr, &(regs.theFpRegs), sizeof(prfpregset_t));
515     
516     if (write(ctl_fd(), fpbuf, fpbufsize) != fpbufsize) {
517         perror("restoreRegisters FPR write");
518         return false;
519     }
520     return true;
521
522 }
523
524 // Determine if the LWP in question is in a system call.
525 bool dyn_lwp::executingSystemCall()
526 {
527   lwpstatus_t status;
528   if (!get_status(&status)) return false;
529   // Old-style
530   if (status.pr_syscall > 0 && // If we're in a system call
531       status.pr_why != PR_SYSEXIT) {
532       stoppedSyscall_ = status.pr_syscall;
533       if (abortSyscall()) {
534           // Not in a syscall any more :)
535           return false;
536       }
537       else {
538           return true;
539       }
540   }
541   
542 #if defined(AIX_PROC)
543   if (status.pr_why == PR_SIGNALLED &&
544       status.pr_what == SIGSTOP) {
545       // We can't operate on a process in SIGSTOP, so clear it
546       proc()->getRepresentativeLWP()->clearSignal();
547   }
548   
549   // I've seen cases where we're apparently not in a system
550   // call, but can't write registers... we'll label this case
551   // a syscall for now
552   const int regbufsize = sizeof(long) + sizeof(prgregset_t);
553   char regbuf[regbufsize]; long *regbufptr = (long *)regbuf;
554   *regbufptr = PCSREG; regbufptr++;
555   memcpy(regbufptr, &(status.pr_reg), sizeof(prgregset_t));
556   int writesize = write(ctl_fd(), regbuf, regbufsize);
557   if (writesize == -1) {
558       return true;
559   }
560 #endif
561   return false;
562 }
563
564
565 bool dyn_lwp::changePC(Address addr, struct dyn_saved_regs *regs)
566 {
567     // Don't change the contents of regs if given
568     dyn_saved_regs local;
569     if (!regs) {
570         getRegisters(&local);
571     } else {
572         memcpy(&local, regs, sizeof(struct dyn_saved_regs));
573     }
574
575     // Compatibility: we don't use PCSVADDR on Solaris because AIX doesn't 
576     // support it
577     // nPC MUST be set before PC! On platforms that don't have it,
578     // nPC will be overwritten by the PC write
579     GETREG_nPC(local.theIntRegs) = addr + sizeof(instruction);
580     GETREG_PC(local.theIntRegs) = addr;
581
582     if (!restoreRegisters(local))
583         return false;
584     
585     dyn_saved_regs check;
586     getRegisters(&check);
587     assert(GETREG_PC(local.theIntRegs) == GETREG_PC(check.theIntRegs));
588
589     return true;
590 }
591
592 #if defined(i386_unknown_solaris2_5)
593 bool process::changeIntReg(int reg, Address val) {
594    assert(status_ == stopped); // /proc will require this
595
596    prgregset_t theIntRegs;
597    dyn_lwp *replwp = getRepresentativeLWP();
598    if (ioctl(replwp->get_fd(), PIOCGREG, &theIntRegs) == -1) {
599       perror("dyn_lwp::changeIntReg");
600       if (errno == EBUSY) {
601          cerr << "It appears that the process wasn't stopped in the eyes of /proc" << endl;
602          assert(false);
603       }
604       return false;
605    }
606
607    theIntRegs[reg] = val;
608
609    if (ioctl(replwp->get_fd(), PIOCSREG, &theIntRegs) == -1) {
610       perror("process::changeIntReg PIOCSREG");
611       if (errno == EBUSY) {
612          cerr << "It appears that the process wasn't stopped in the eyes of /proc" << endl;
613          assert(false);
614       }
615       return false;
616    }
617
618    return true;
619 }
620 #endif
621
622 // Utility function: get the appropriate lwpstatus_t struct
623 bool dyn_lwp::get_status(lwpstatus_t *status) const
624 {
625     if(!is_attached()) {
626         return false;
627     }
628     
629    if (lwp_id_) {
630       // We're using an lwp file descriptor, so get directly
631       if (pread(status_fd_, 
632                 (void *)status, 
633                 sizeof(lwpstatus_t), 0) != sizeof(lwpstatus_t)) {
634           // When we fork a LWP file might disappear.
635           if (errno != ENOENT) {
636               perror("dyn_lwp::get_status");            
637           }
638          return false;
639       }
640    }
641    else {
642       // No lwp, so we get the whole thing and pick it out
643       pstatus_t procstatus;
644       if (!proc_->get_status(&procstatus)) {
645          return false;
646       }
647       memcpy(status, &(procstatus.pr_lwp), sizeof(lwpstatus_t));
648    }
649    return true;
650 }
651
652 // Read the value of a particular register
653 Address dyn_lwp::readRegister(Register reg)
654 {
655     Address result;
656     dyn_saved_regs regs;
657     getRegisters(&regs);
658     result = GETREG_GPR(regs.theIntRegs, reg);
659     return result;
660 }
661
662 bool dyn_lwp::realLWP_attach_() {
663    char temp[128];
664    sprintf(temp, "/proc/%d/lwp/%d/lwpctl", (int)proc_->getPid(), lwp_id_);
665    ctl_fd_ = P_open(temp, O_WRONLY, 0);
666    if (ctl_fd_ < 0) perror("Opening lwpctl");
667    sprintf(temp, "/proc/%d/lwp/%d/lwpstatus", (int)proc_->getPid(),lwp_id_);
668    status_fd_ = P_open(temp, O_RDONLY, 0);    
669    if (status_fd_ < 0) perror("Opening lwpstatus");
670 #if !defined(AIX_PROC)
671    sprintf(temp, "/proc/%d/lwp/%d/lwpusage", (int)proc_->getPid(), lwp_id_);
672    usage_fd_ = P_open(temp, O_RDONLY, 0);
673 #else
674    usage_fd_ = 0;
675 #endif
676    return true;
677 }
678
679 bool dyn_lwp::representativeLWP_attach_() {
680    /*
681      Open the /proc file corresponding to process pid
682    */
683
684    char temp[128];
685    // Open the process-wise handles
686    sprintf(temp, "/proc/%d/ctl", getPid());
687    ctl_fd_ = P_open(temp, O_WRONLY | O_EXCL, 0);
688    if (ctl_fd_ < 0) perror("Opening (LWP) ctl");
689
690    sprintf(temp, "/proc/%d/status", getPid());
691    status_fd_ = P_open(temp, O_RDONLY, 0);    
692    if (status_fd_ < 0) perror("Opening (LWP) status");
693
694 #if !defined(AIX_PROC)
695    sprintf(temp, "/proc/%d/usage", getPid());
696    usage_fd_ = P_open(temp, O_RDONLY, 0);    
697    if (usage_fd_ < 0) perror("Opening (LWP) usage");
698 #else
699    usage_fd_ = 0;
700 #endif
701
702    as_fd_ = -1;
703    sprintf(temp, "/proc/%d/as", getPid());
704    as_fd_ = P_open(temp, O_RDWR, 0);
705    if (as_fd_ < 0) perror("Opening as fd");
706
707 #if !defined(AIX_PROC)
708    sprintf(temp, "/proc/%d/auxv", getPid());
709    auxv_fd_ = P_open(temp, O_RDONLY, 0);
710    if (auxv_fd_ < 0) perror("Opening auxv fd");
711 #else
712    // AIX doesn't have the auxv file
713    auxv_fd_ = 0;
714 #endif
715
716    sprintf(temp, "/proc/%d/map", getPid());
717    map_fd_ = P_open(temp, O_RDONLY, 0);
718    if (map_fd_ < 0) perror("map fd");
719
720    sprintf(temp, "/proc/%d/psinfo", getPid());
721    ps_fd_ = P_open(temp, O_RDONLY, 0);
722    if (ps_fd_ < 0) perror("Opening ps fd");
723
724    sprintf(temp, "/proc/%d/status", getPid());
725    status_fd_ = P_open(temp, O_RDONLY, 0);
726    if (status_fd_ < 0) perror("Opening status fd");
727
728    lwpstatus_t status;
729
730    // special for aix: we grab the status and clear the STOP
731    // signal (if any)
732    is_attached_ = true;
733    get_status(&status);
734
735
736    if (status.pr_why == PR_SIGNALLED &&
737        status.pr_what == SIGSTOP) {
738        clearSignal();
739    }
740
741   // Abort a system call if we're in it
742   abortSyscall();
743
744    return true;
745 }
746
747 // Close FDs opened above
748 void dyn_lwp::realLWP_detach_()
749 {
750    assert(is_attached());  // dyn_lwp::detach() shouldn't call us otherwise
751       
752    // First we want to clear any signal which might be pending
753    // for the process. Otherwise, when we detach the process has
754    // a signal sent that it may have no clue about
755    // But we can't do that here -- all FDs associated with the process
756    // are closed.
757    close(ctl_fd_);
758    close(status_fd_);
759    close(usage_fd_);
760    is_attached_ = false;
761 }
762
763 // Close FDs opened above
764 void dyn_lwp::representativeLWP_detach_()
765 {
766    assert(is_attached());  // dyn_lwp::detach() shouldn't call us otherwise
767       
768    // First we want to clear any signal which might be pending
769    // for the process. Otherwise, when we detach the process has
770    // a signal sent that it may have no clue about
771    // But we can't do that here -- all FDs associated with the process
772    // are closed.
773    close(ctl_fd_);
774    close(status_fd_);
775    close(usage_fd_);
776    close(as_fd_);
777    close(ps_fd_);
778    close(status_fd_);
779    is_attached_ = false;
780 }
781
782 /*
783  * Process-wide /proc operations
784  */
785
786 bool process::setProcessFlags()
787 {
788     long command[2];
789
790     // Unset all flags
791     command[0] = PCUNSET;
792     command[1] = PR_BPTADJ | PR_MSACCT | PR_RLC | PR_KLC | PR_FORK;
793
794     dyn_lwp *replwp = getRepresentativeLWP();
795     if (write(replwp->ctl_fd(), command, 2*sizeof(long)) != 2*sizeof(long)) {
796         perror("installProcessFlags: PRUNSET");
797         return false;
798     }
799     command[0] = PCSET;
800
801     long flags = PR_BPTADJ | PR_MSACCT | PR_FORK;
802
803     command[1] = flags;
804
805     if (write(replwp->ctl_fd(), command, 2*sizeof(long)) != 2*sizeof(long)) {
806         perror("installProcessFlags: PCSET");
807         return false;
808     }
809
810    // step 2) /proc PIOCSTRACE: define which signals should be
811    // forwarded to daemon These are (1) SIGSTOP and (2) either
812    // SIGTRAP (sparc) or SIGILL (x86), to implement inferiorRPC
813    // completion detection.
814    // Also detect SIGCONT so that we know if a user has restarted
815    // an application.
816   
817    proc_sigset_t sigs;
818     
819    premptyset(&sigs);
820    praddset(&sigs, SIGSTOP);
821     
822    praddset(&sigs, SIGTRAP);
823     
824    praddset(&sigs, SIGCONT);
825    praddset(&sigs, SIGBUS);
826    praddset(&sigs, SIGSEGV);
827    praddset(&sigs, SIGILL);
828     
829    const int bufsize = sizeof(long) + sizeof(proc_sigset_t);
830    char buf[bufsize]; 
831    long *bufptr = (long *) buf;
832    *bufptr = PCSTRACE;
833    bufptr++;
834    memcpy(bufptr, &sigs, sizeof(proc_sigset_t));
835
836    if(write(replwp->ctl_fd(), buf, bufsize) != bufsize) {
837       perror("attach: PCSTRACE");
838       return false;
839    }
840
841
842     return true;
843 }
844
845 bool process::unsetProcessFlags()
846 {
847     long command[2];
848
849     if (!isAttached()) return false;
850     // Unset all flags
851     command[0] = PCUNSET;
852     command[1] = PR_BPTADJ | PR_MSACCT | PR_RLC | PR_KLC | PR_FORK;
853
854     dyn_lwp *replwp = getRepresentativeLWP();
855     if (write(replwp->ctl_fd(), command, 2*sizeof(long)) != 2*sizeof(long)) {
856         perror("unsetProcessFlags: PRUNSET");
857         return false;
858     }
859
860     proc_sigset_t sigs;
861     premptyset(&sigs);
862     const int sigbufsize = sizeof(long) + sizeof(proc_sigset_t);
863     char sigbuf[sigbufsize]; long *sigbufptr = (long *)sigbuf;
864
865     sigbufptr = (long *)sigbuf;
866     *sigbufptr = PCSTRACE;
867     if (write(replwp->ctl_fd(), sigbuf, sigbufsize) != sigbufsize) {
868         perror("unsetProcessFlags: PCSTRACE");
869         return false;
870     }
871     
872     return true;
873 }
874
875 // AIX requires us to re-open the process-wide handles after
876 // an exec call
877
878 #if defined(AIX_PROC)
879 void dyn_lwp::reopen_fds() {
880         // Reopen the process-wide handles
881     char temp[128];
882
883     close(as_fd_);
884     sprintf(temp, "/proc/%d/as", getPid());
885     as_fd_ = P_open(temp, O_RDWR, 0);
886     if (as_fd_ <= 0) perror("Opening as fd");
887 #if !defined(AIX_PROC)
888     close(auxv_fd_);
889     sprintf(temp, "/proc/%d/auxv", getPid());
890     auxv_fd_ = P_open(temp, O_RDONLY, 0);
891     if (auxv_fd_ <= 0) perror("Opening auxv fd");
892 #else
893     // AIX doesn't have the auxv file
894     auxv_fd_ = 0;
895 #endif
896
897     close(map_fd_);
898     sprintf(temp, "/proc/%d/map", getPid());
899     map_fd_ = P_open(temp, O_RDONLY, 0);
900     if (map_fd_ <= 0) perror("map fd");
901
902     close(ps_fd_);
903     sprintf(temp, "/proc/%d/psinfo", getPid());
904     ps_fd_ = P_open(temp, O_RDONLY, 0);
905     if (ps_fd_ <= 0) perror("Opening ps fd");
906
907     close(status_fd_);
908     sprintf(temp, "/proc/%d/status", getPid());
909     status_fd_ = P_open(temp, O_RDONLY, 0);
910     if (status_fd_ <= 0) perror("Opening status fd");
911 }
912 #endif
913
914 bool process::isRunning_() const {
915     // We can key off the representative LWP
916     return getRepresentativeLWP()->isRunning();
917 }
918
919 /*
920    terminate execution of a process
921  */
922 terminateProcStatus_t process::terminateProc_()
923 {
924   // Two kill methods: polite and unpolite. Not sure why we use
925   // polite, but hey...
926
927   // Polite: we're attached, and use a /proc command.
928   // Unpolite: we're not attached, and kill -9
929
930   if (isAttached()) {
931     // these next two lines are a hack used to get the poll call initiated
932     // by checkForAndHandleProcessEvents() in process::terminateProc to
933     // still check process for events if it was previously stopped
934     if(status() == stopped)
935       status_ = running;
936
937     long command[2];
938     command[0] = PCKILL;
939     command[1] = SIGKILL;
940     dyn_lwp *cntl_lwp = getRepresentativeLWP();
941     if (cntl_lwp) {
942       if (write(cntl_lwp->ctl_fd(), 
943                 command, 2*sizeof(long)) != 2*sizeof(long)) {
944         perror("terminateProc: PCKILL");
945         // TODO: what gets returned if the process is already dead?
946         // proc man page doesn't say.
947         return terminateFailed;
948       }
949       return terminateSucceeded;
950     }
951     else {
952       // Uh...
953       return terminateFailed;
954     }
955   }
956   else {
957     // We may be detached. Go for it the old-fashioned way.
958     if (kill( getPid(), SIGKILL )) {
959         return terminateFailed;
960     }
961     else {
962       // alreadyTerminated... since we don't want to wait
963       // for a "I'm dead" message.
964       return alreadyTerminated;
965     }
966   }
967   assert(0 && "Unreachable");
968   return terminateFailed;
969 }
970
971 bool dyn_lwp::waitUntilStopped() {
972    return true;
973 }
974
975 bool process::waitUntilStopped() {
976    return true;
977 }
978
979 bool dyn_lwp::writeTextWord(caddr_t inTraced, int data) {
980    //  cerr << "writeTextWord @ " << (void *)inTraced << endl; cerr.flush();
981    return writeDataSpace(inTraced, sizeof(int), (caddr_t) &data);
982 }
983
984 bool dyn_lwp::writeTextSpace(void *inTraced, u_int amount, const void *inSelf)
985 {
986    //  cerr << "writeTextSpace pid=" << getPid() << ", @ " << (void *)inTraced
987    //       << " len=" << amount << endl; cerr.flush();
988    return writeDataSpace(inTraced, amount, inSelf);
989 }
990
991 bool dyn_lwp::readTextSpace(void *inTraced, u_int amount, const void *inSelf) {
992    return readDataSpace(inTraced, amount, const_cast<void *>(inSelf));
993 }
994
995 bool dyn_lwp::writeDataSpace(void *inTraced, u_int amount, const void *inSelf)
996 {
997    ptraceOps++; ptraceBytes += amount;
998
999    //  cerr << "process::writeDataSpace_ pid " << getPid() << " writing "
1000    //       << amount << " bytes at loc " << inTraced << endl;
1001 #if defined(BPATCH_LIBRARY)
1002 #if defined (sparc_sun_solaris2_4)
1003         if(proc_->collectSaveWorldData &&  ((Address) inTraced) >
1004       proc_->getDyn()->getlowestSObaseaddr() )
1005    {
1006                 shared_object *sh_obj = NULL;
1007                 bool result = false;
1008                 for(unsigned i=0;
1009           proc_->shared_objects && !result && i<proc_->shared_objects->size();
1010           i++)
1011       {
1012                         sh_obj = (*proc_->shared_objects)[i];
1013                         result = sh_obj->isinText((Address) inTraced);
1014                 }
1015                 if( result  ){
1016          /*     bperr(" write at %lx in %s amount %x insn: %x \n", 
1017                                 (off_t)inTraced, sh_obj->getName().c_str(), amount,
1018             *(unsigned int*) inSelf);
1019             */  
1020                         sh_obj->setDirty();     
1021                 }
1022         }
1023 #endif
1024 #endif
1025    off64_t loc;
1026    // Problem: we may be getting a address with the high bit
1027    // set. So how to convince the system that it's not negative?
1028    loc = (off64_t) ((unsigned) inTraced);
1029
1030    int written = pwrite64(as_fd(), inSelf, amount, loc);
1031    if(written != (int)amount) {
1032       perror("writeDataSpace");
1033       return false;
1034    }
1035     
1036    return true;
1037 }
1038
1039 bool dyn_lwp::readDataSpace(const void *inTraced, u_int amount, void *inSelf) {
1040     ptraceOps++; ptraceBytes += amount;
1041
1042     off64_t loc;
1043     loc = (off64_t) ((unsigned) inTraced);
1044
1045     if(pread64(as_fd(), inSelf, amount, loc) != (int)amount) {
1046         perror("readDataSpace");
1047         bperr( "From 0x%x (mutator) to 0x%x (mutatee), %d bytes\n",
1048                 (int)inSelf, (int)inTraced, amount);
1049         return false;
1050     }
1051     return true;
1052 }
1053
1054
1055 bool process::get_status(pstatus_t *status) const
1056 {
1057     if (!isAttached()) return false;
1058     if (!getRepresentativeLWP()->is_attached()) return false;
1059    
1060     if(pread(getRepresentativeLWP()->status_fd(), (void *)status,
1061              sizeof(pstatus_t), 0) != sizeof(pstatus_t)) {
1062         perror("process::get_status");
1063         return false;
1064     }
1065     
1066     return true;
1067 }
1068
1069 bool process::set_entry_syscalls(sysset_t *entry)
1070 {
1071     if (!isAttached()) return false;
1072     
1073     int bufentrysize = sizeof(long) + SYSSET_SIZE(entry);
1074     char *bufentry = new char[bufentrysize]; long *bufptr = (long *)bufentry;
1075     
1076     // Write entry syscalls
1077     *bufptr = PCSENTRY; bufptr++;
1078     memcpy(bufptr, entry, SYSSET_SIZE(entry));
1079
1080     dyn_lwp *replwp = getRepresentativeLWP();        
1081     if (write(replwp->ctl_fd(), bufentry, bufentrysize) != bufentrysize){
1082        delete [] bufentry;
1083        return false;
1084     }
1085
1086     delete [] bufentry;
1087     return true;    
1088 }
1089
1090 bool process::set_exit_syscalls(sysset_t *exit)
1091 {
1092     if (!isAttached()) return false;
1093     
1094     int bufexitsize = sizeof(long) + SYSSET_SIZE(exit);
1095     char *bufexit = new char[bufexitsize]; long *bufptr = (long *)bufexit;
1096     *bufptr = PCSEXIT; bufptr++;
1097     memcpy(bufptr, exit, SYSSET_SIZE(exit));
1098
1099     dyn_lwp *replwp = getRepresentativeLWP();        
1100     if (write(replwp->ctl_fd(), bufexit, bufexitsize) != bufexitsize){
1101        delete [] bufexit;
1102        return false;
1103     }
1104     delete [] bufexit;
1105     return true;    
1106 }
1107
1108 #if defined(AIX_PROC)
1109 extern void generateBreakPoint(instruction &insn);
1110 #endif
1111
1112 syscallTrap *process::trapSyscallExitInternal(Address syscall)
1113 {
1114     syscallTrap *trappedSyscall = NULL;
1115
1116     // First, the cross-platform bit. If we're already trapping
1117     // on this syscall, then increment the reference counter
1118     // and return
1119
1120     for (unsigned iter = 0; iter < syscallTraps_.size(); iter++) {
1121         if (syscallTraps_[iter]->syscall_id == syscall) {
1122             trappedSyscall = syscallTraps_[iter];
1123             break;
1124         }
1125     }
1126
1127     if (trappedSyscall) {
1128         // That was easy...
1129         trappedSyscall->refcount++;
1130         //bperr( "Bumping refcount for syscall %d to %d\n",
1131         //        (int)trappedSyscall->syscall_id, trappedSyscall->refcount);
1132         return trappedSyscall;
1133     }
1134     else {
1135         // Okay, we haven't trapped this system call yet.
1136         // Things to do:
1137         // 1) Get the original value
1138         // 2) Place a trap
1139         // 3) Create a new syscallTrap object and return it
1140         trappedSyscall = new syscallTrap;
1141         trappedSyscall->refcount = 1;
1142         trappedSyscall->syscall_id = (int) syscall;
1143
1144         //bperr( "  trapping syscall %d for 1st time (%d)\n",
1145         //       (int)trappedSyscall->syscall_id, trappedSyscall->refcount);
1146         
1147 #if defined(AIX_PROC) 
1148         // AIX does some weird things, as we can't modify a thread
1149         // at a system call exit -- this means that using /proc
1150         // doesn't get us anywhere.
1151         // The "address" of the system call is actually the LWP
1152         // in the call
1153         dyn_lwp *syslwp = getLWP((unsigned) syscall);
1154         Frame frame = syslwp->getActiveFrame();
1155         Frame callerFrame = frame.getCallerFrame();
1156         
1157         Address origLR;
1158         readDataSpace((void *)(callerFrame.getFP() + 8),
1159                       sizeof(Address),
1160                       (void *)&origLR, false);
1161         trappedSyscall->origLR = origLR;
1162         
1163         Address trapAddr = inferiorMalloc(sizeof(instruction));
1164         trappedSyscall->trapAddr = trapAddr;
1165         instruction insn;
1166         generateBreakPoint(insn);
1167
1168         writeDataSpace((void *)trapAddr, sizeof(instruction),
1169                        (void *)&insn);
1170         writeDataSpace((void *)(callerFrame.getFP() + 8), 
1171                        sizeof(Address),
1172                        (void *)&trapAddr);
1173 #else
1174         sysset_t *cur_syscalls = SYSSET_ALLOC(getPid());
1175
1176         if (!get_exit_syscalls(cur_syscalls)) return NULL;
1177         if (prissyssetmember(cur_syscalls, trappedSyscall->syscall_id))
1178             // Surprising case... but it's possible as we trap fork and exec
1179             trappedSyscall->orig_setting = 1;
1180         else
1181             trappedSyscall->orig_setting = 0;
1182
1183         // 2) Place a trap
1184         praddsysset(cur_syscalls, trappedSyscall->syscall_id);
1185         if (!set_exit_syscalls(cur_syscalls)) return false;
1186         
1187         //bperr("PCSexit for %d, orig %d\n", 
1188         //trappedSyscall->syscall_id, trappedSyscall->orig_setting);
1189 #endif
1190         // Insert into the list of trapped syscalls
1191         syscallTraps_ += (trappedSyscall);
1192
1193         return trappedSyscall;
1194     }
1195     // Should never reach here.
1196     return NULL;
1197 }
1198
1199 bool process::clearSyscallTrapInternal(syscallTrap *trappedSyscall) {
1200     // Decrement the reference count, and if it's 0 remove the trapped
1201     // system call
1202     assert(trappedSyscall->refcount > 0);
1203
1204     trappedSyscall->refcount--;
1205     if (trappedSyscall->refcount > 0) {
1206         //bperr( "Refcount on syscall %d reduced to %d\n",
1207         //        (int)trappedSyscall->syscall_id,
1208         //        trappedSyscall->refcount);
1209         return true;
1210     }
1211     // Erk... it hit 0. Remove the trap at the system call
1212 #if defined(AIX_PROC) 
1213     dyn_lwp *lwp = getLWP(trappedSyscall->syscall_id);
1214     inferiorFree(trappedSyscall->trapAddr);
1215     lwp->changePC(trappedSyscall->origLR, NULL);
1216 #else
1217     sysset_t *cur_syscalls = SYSSET_ALLOC(getPid());
1218
1219     if (!get_exit_syscalls(cur_syscalls)) return false;
1220     if (!trappedSyscall->orig_setting) {
1221         prdelsysset(cur_syscalls, trappedSyscall->syscall_id);
1222     }
1223     
1224     if (!set_exit_syscalls(cur_syscalls)) return false;
1225     
1226
1227 #endif
1228     // Now that we've reset the original behavior, remove this
1229     // entry from the vector
1230     pdvector<syscallTrap *> newSyscallTraps;
1231     for (unsigned iter = 0; iter < syscallTraps_.size(); iter++) {
1232         if (trappedSyscall != syscallTraps_[iter])
1233             newSyscallTraps.push_back(syscallTraps_[iter]);
1234     }
1235     syscallTraps_ = newSyscallTraps;
1236     delete trappedSyscall;
1237     
1238     return true;
1239 }
1240
1241 Address dyn_lwp::getCurrentSyscall() {
1242     
1243     // Return the system call we're currently in
1244     lwpstatus_t status;
1245     if (!get_status(&status)) {
1246         bperr( "Failed to get status\n");
1247         return 0;
1248     }
1249 #if defined(AIX_PROC)
1250     return get_lwp_id();
1251 #else
1252     return status.pr_syscall;
1253 #endif
1254 }
1255
1256
1257
1258 bool dyn_lwp::stepPastSyscallTrap()
1259 {
1260 #if defined(AIX_PROC)
1261     // What is something else doing hitting our trap?
1262     assert(0);
1263 #endif
1264     // Nice... on /proc systems we don't need to do anything here
1265     return true;
1266 }
1267
1268 // Check if a LWP has hit a trap we inserted to catch the exit of a
1269 // system call trap.
1270 // Return values:
1271 // 0: did not trap at the exit of a syscall
1272 // 1: Trapped, but did not have a syscall trap placed for this LWP
1273 // 2: Trapped with a syscall trap desired.
1274 int dyn_lwp::hasReachedSyscallTrap() {
1275 #if defined(AIX_PROC) 
1276     if (!trappedSyscall_) return 0;
1277     
1278     Frame frame = getActiveFrame();
1279     
1280     if (frame.getPC() == trappedSyscall_->trapAddr)
1281         return 2;
1282 #else
1283     Address syscall;
1284     // Get the status of the LWP
1285     lwpstatus_t status;
1286     if (!get_status(&status)) {
1287         bperr( "Failed to get thread status\n");
1288         return 0;
1289     }
1290     
1291     if (status.pr_why != PR_SYSEXIT) {
1292         return 0;
1293     }
1294     syscall = status.pr_what;
1295     
1296     if (trappedSyscall_ && syscall == trappedSyscall_->syscall_id) {
1297         return 2;
1298     }
1299     // Unfortunately we can't check a recorded system call trap,
1300     // since we don't have one saved. So do a scan through all traps the
1301     // process placed
1302     if (proc()->checkTrappedSyscallsInternal(syscall))
1303         return 1;
1304 #endif
1305
1306     // This is probably an error case... but I'm not sure.
1307     return 0;
1308 }
1309
1310 procSyscall_t decodeSyscall(process *p, procSignalWhat_t syscall)
1311 {
1312    int pid = p->getPid();
1313
1314     if (syscall == SYSSET_MAP(SYS_fork, pid) ||
1315         syscall == SYSSET_MAP(SYS_fork1, pid) ||
1316         syscall == SYSSET_MAP(SYS_vfork, pid))
1317         return procSysFork;
1318     if (syscall == SYSSET_MAP(SYS_exec, pid) || 
1319         syscall == SYSSET_MAP(SYS_execve, pid))
1320         return procSysExec;
1321     if (syscall == SYSSET_MAP(SYS_exit, pid))
1322         return procSysExit;
1323
1324
1325     return procSysOther;
1326 }
1327
1328
1329
1330 int decodeProcStatus(process *,
1331                      lwpstatus_t status,
1332                      procSignalWhy_t &why,
1333                      procSignalWhat_t &what,
1334                      procSignalInfo_t &info) {
1335    info = GETREG_INFO(status.pr_reg);
1336
1337    switch (status.pr_why) {
1338      case PR_SIGNALLED:
1339         why = procSignalled;
1340         what = status.pr_what;
1341         break;
1342      case PR_SYSENTRY:
1343         why = procSyscallEntry;
1344         what = status.pr_what;
1345         
1346 #if defined(AIX_PROC)
1347         // We actually pull from the syscall argument vector
1348         if (status.pr_nsysarg > 0)
1349            info = status.pr_sysarg[0];
1350         else
1351            info = 0;
1352 #endif
1353         break;
1354      case PR_SYSEXIT:
1355         why = procSyscallExit;
1356         what = status.pr_what;
1357         
1358 #if defined(AIX_PROC)
1359         // This from the proc header file: system returns are
1360         // left in pr_sysarg[0]. NOT IN MAN PAGE.
1361         info = status.pr_sysarg[0];
1362 #endif
1363         break;
1364      case PR_REQUESTED:
1365         // We don't expect PR_REQUESTED in the signal handler
1366         assert(0 && "PR_REQUESTED not handled");
1367 #if defined(PR_SUSPENDED)
1368      case PR_SUSPENDED:
1369         // I'm seeing this state at times with a forking multi-threaded
1370         // child process, currently handling by just continuing the process
1371         why = procSuspended;
1372         break;
1373 #endif
1374      case PR_JOBCONTROL:
1375      case PR_FAULTED:
1376      default:
1377         assert(0);
1378         break;
1379    }
1380    
1381    return 1;
1382 }
1383
1384 int showProcStatus(lwpstatus_t status)
1385 {
1386    switch (status.pr_why) {
1387      case PR_SIGNALLED:
1388         cerr << "PR_SIGNALED, what: " << (int)status.pr_what << endl;
1389         break;
1390      case PR_SYSENTRY:
1391         cerr << "PR_SYSENTRY, what: " << (int)status.pr_what << endl;
1392         break;
1393      case PR_SYSEXIT:
1394         cerr << "PR_SYSEXIT, what: " << (int)status.pr_what << endl;
1395         break;
1396      case PR_REQUESTED:
1397         cerr << "PR_REQUESTED\n";
1398         break;
1399 #if defined(PR_SUSPENDED)
1400      case PR_SUSPENDED:
1401         // I'm seeing this state at times with a forking multi-threaded
1402         // child process, currently handling by just continuing the process
1403         cerr << "PR_SUSPENDED\n";
1404         break;
1405 #endif
1406      case PR_JOBCONTROL:
1407      case PR_FAULTED:
1408      default:
1409         cerr << "OTHER\n";
1410         assert(0);
1411         break;
1412    }
1413    return 1;
1414 }
1415
1416 procevent *find_matching_event(const pdvector<procevent *> &events,
1417                                process *proc, procSignalWhy_t  why,
1418                                procSignalWhat_t what) {
1419    procevent *matching_ev = NULL;
1420    for(unsigned i=0; i<events.size(); i++) {
1421       procevent *cur_event = events[i];
1422       if(cur_event->proc == proc && cur_event->why == why &&
1423          cur_event->what == what) {
1424          // assume that there's at most one matching event
1425          assert(matching_ev == NULL);
1426          matching_ev = cur_event;
1427       }
1428    }
1429
1430    return matching_ev;
1431 }
1432                                
1433 // returns true if updated events structure for this lwp 
1434 bool updateEventsWithLwpStatus(process *curProc, dyn_lwp *lwp,
1435                                pdvector<procevent *> *events)
1436 {
1437
1438    lwpstatus_t lwpstatus;
1439    bool res = lwp->get_status(&lwpstatus);
1440
1441    if(res == false) {
1442       return false;
1443    }
1444
1445    // This is the "why" for the lwps that were stopped because some other
1446    // lwp stopped for an interesting reason.  We don't care about lwps
1447    // that stopped for this reason.
1448    if(lwpstatus.pr_why == PR_REQUESTED) {
1449       return false;
1450    }
1451    
1452    procSignalWhy_t  why  = procUndefined;
1453    procSignalWhat_t what = 0;
1454    procSignalInfo_t info = 0;
1455
1456    if(!decodeProcStatus(curProc, lwpstatus, why, what, info))
1457       return false;
1458    
1459    procevent *matching_event =
1460       find_matching_event(*events, curProc, why, what);
1461
1462    if(matching_event == NULL) {
1463       procevent *new_event = new procevent;
1464       new_event->proc = curProc;
1465       new_event->lwp  = lwp;
1466       new_event->why  = why;
1467       new_event->what = what;
1468       new_event->info = info;
1469       (*events).push_back(new_event);
1470    } else {
1471       matching_event->lwp = lwp;
1472    }
1473    
1474    return true;
1475 }
1476
1477 void fillInPollEvents(struct pollfd fds, process *curProc,
1478                       pdvector<procevent *> *events)
1479 {
1480    if (fds.revents & POLLHUP) {
1481       procevent *new_event = new procevent;
1482       new_event->proc = curProc;
1483       new_event->lwp = curProc->getRepresentativeLWP();
1484       
1485       // True if the process exited out from under us
1486       int status;
1487       int ret;
1488       do {
1489           ret = waitpid(curProc->getPid(), &status, 0);
1490       } while ((ret < 0) && (errno == EINTR));
1491       if (ret < 0) {
1492           // This means that the application exited, but was not our child
1493           // so it didn't wait around for us to get it's return code.  In
1494           // this case, we can't know why it exited or what it's return
1495           // code was.
1496           ret = curProc->getPid();
1497           status = 0;
1498           // is this the bug??
1499           // processVec[curr]->continueProc_();
1500       }
1501       
1502       decodeWaitPidStatus(curProc, status, &new_event->why, &new_event->what);
1503       (*events).push_back(new_event);
1504       return;
1505    }
1506
1507    lwpstatus_t procstatus;
1508    if(! curProc->getRepresentativeLWP()->get_status(&procstatus))
1509       return;
1510    unsigned lwp_to_use = (unsigned) procstatus.pr_lwpid;
1511
1512    // copied from old code, must not care about events that don't stop proc
1513    if(! (procstatus.pr_flags & PR_STOPPED || procstatus.pr_flags & PR_ISTOP) )
1514       return;
1515
1516    dictionary_hash_iter<unsigned, dyn_lwp *> lwp_iter(curProc->real_lwps);
1517    dyn_lwp *cur_lwp;
1518    unsigned index;
1519    dyn_lwp *replwp = curProc->getRepresentativeLWP();
1520    int numreal_lwps = curProc->real_lwps.size();
1521
1522    bool added_an_event = false;
1523    if(numreal_lwps == 0)
1524       added_an_event = updateEventsWithLwpStatus(curProc, replwp, events);
1525    else {
1526       while (lwp_iter.next(index, cur_lwp)) {
1527         if(cur_lwp->get_lwp_id() != lwp_to_use)
1528           continue;
1529         if(updateEventsWithLwpStatus(curProc, cur_lwp, events))
1530           added_an_event = true;
1531       }
1532    }
1533
1534    /*
1535    if(added_an_event == false) {
1536       assert(false);
1537    }
1538    */
1539 }
1540
1541 #if defined(bug_aix_proc_broken_fork)
1542
1543 int decodeRTSignal(process *proc,
1544                    procSignalWhy_t &why,
1545                    procSignalWhat_t &what,
1546                    procSignalInfo_t &info)
1547 {
1548    // We've received a signal we believe was sent
1549    // from the runtime library. Check the RT lib's
1550    // status variable and return it.
1551    // These should be made constants
1552    if (!proc) return 0;
1553
1554    pdstring status_str = pdstring("DYNINST_instSyscallState");
1555    pdstring arg_str = pdstring("DYNINST_instSyscallArg1");
1556
1557    int status;
1558    Address arg;
1559
1560    bool err = false;
1561    Address status_addr = proc->findInternalAddress(status_str, false, err);
1562    if (err) {
1563       // Couldn't find symbol
1564       return 0;
1565    }
1566
1567    if (!proc->readDataSpace((void *)status_addr, sizeof(int), 
1568                             &status, true)) {
1569       return 0;
1570    }
1571
1572    if (status == 0) {
1573       return 0; // Nothing to see here
1574    }
1575
1576    Address arg_addr = proc->findInternalAddress(arg_str, false, err);
1577    if (err) {
1578       return 0;
1579    }
1580     
1581    if (!proc->readDataSpace((void *)arg_addr, sizeof(Address),
1582                             &arg, true))
1583       assert(0);
1584    info = (procSignalInfo_t)arg;
1585    switch(status) {
1586      case 1:
1587         /* Entry to fork */
1588         why = procSyscallEntry;
1589         what = SYS_fork;
1590         break;
1591      case 2:
1592         why = procSyscallExit;
1593         what = SYSSET_MAP(SYS_fork, proc->getPid());
1594         break;
1595      case 3:
1596         /* Entry to exec */
1597         why = procSyscallEntry;
1598         what = SYS_exec;
1599         break;
1600      case 4:
1601         /* Exit of exec, unused */
1602         break;
1603      case 5:
1604         /* Entry of exit, used for the callback. We need to trap before
1605            the process has actually exited as the callback may want to
1606            read from the process */
1607         why = procSyscallEntry;
1608         what = SYS_exit;
1609         break;
1610      default:
1611         assert(0);
1612         break;
1613    }
1614    return 1;
1615
1616 }
1617 #endif
1618
1619 void specialHandlingOfEvents(const pdvector<procevent *> &events) {
1620    for(unsigned i=0; i<events.size(); i++) {
1621       procevent *cur_event = events[i];
1622       process *cur_proc = cur_event->proc;
1623
1624 #if defined(os_aix)
1625       if (cur_event->why == procSignalled && cur_event->what == SIGSTOP) {
1626          // On AIX we can't manipulate a process stopped on a
1627          // SIGSTOP... in any case, we clear it.
1628          // No other signal exhibits this behavior.
1629          cur_proc->getRepresentativeLWP()->clearSignal();
1630       }
1631 #endif
1632
1633 #if defined(bug_aix_proc_broken_fork)
1634       if (cur_event->why == procSignalled && cur_event->what == SIGSTOP) {
1635           // Possibly a fork stop in the RT library
1636           decodeRTSignal(cur_proc, cur_event->why, cur_event->what, cur_event->info);
1637       }
1638 #endif
1639
1640       if(cur_event->lwp != NULL) {
1641          // not necessary now that have lwp info in the event info
1642          if(cur_event->why == procSyscallExit && cur_event->what == 2) {
1643             cur_proc->setLWPStoppedFromForkExit(
1644                                         cur_event->lwp->get_lwp_id());
1645          }
1646       }
1647    }
1648 }      
1649
1650 // Get and decode a signal for a process
1651 // We poll /proc for process events, and so it's possible that
1652 // we'll get multiple hits. In this case we return one and queue
1653 // the rest. Further calls of decodeProcessEvent will burn through
1654 // the queue until there are none left, then re-poll.
1655 // Return value: 0 if nothing happened, or process pointer
1656
1657 // the pertinantLWP and wait_options are ignored on Solaris, AIX
1658
1659 bool signalHandler::checkForProcessEvents(pdvector<procevent *> *events,
1660                                           int wait_arg, int &timeout)
1661 {
1662    extern pdvector<process*> processVec;
1663    bool any_active_procs = false;
1664    struct pollfd fds[OPEN_MAX];  // argument for poll
1665    int num_fds_to_watch = processVec.size();
1666
1667    for(unsigned u = 0; u < processVec.size(); u++) {
1668        process *lproc = processVec[u];
1669        if(lproc && (lproc->status() == running || lproc->status() == neonatal))
1670        {
1671            if (wait_arg == -1 || lproc->getPid() == wait_arg) {
1672                fds[u].fd = lproc->getRepresentativeLWP()->status_fd();
1673                any_active_procs = true;
1674            } else {
1675                fds[u].fd = -1;
1676            }                
1677        } else {
1678            fds[u].fd = -1;
1679        }        
1680        fds[u].events = POLLPRI;
1681        fds[u].revents = 0;
1682    }
1683    
1684    if(any_active_procs == false) {
1685        return false;
1686    }
1687    
1688    int num_selected_fds = poll(fds, num_fds_to_watch, timeout);
1689    if (num_selected_fds <= 0) {
1690        if (num_selected_fds < 0) {
1691            perror("checkForProcessEvents: poll failed");
1692        }
1693        else {
1694          // return of 0 indicates timeout
1695          timeout = 0;
1696        }
1697        return false;
1698    }
1699    //handled_fds = 0; handled_fds < num_selected_fds; ) {
1700    int handled_fds = 0;
1701    for(int i=0; i<num_fds_to_watch; i++) {
1702        if(fds[i].revents == 0)
1703            continue;
1704        
1705        handled_fds++;  // going to handle this now
1706        process *curProc = processVec[i];
1707        curProc->set_status(stopped);
1708        fillInPollEvents(fds[i], curProc, events);
1709    }
1710    assert(num_selected_fds == handled_fds);
1711    
1712    specialHandlingOfEvents(*events);
1713    if((*events).size()) {
1714        return true;
1715    } else
1716        return false;
1717 }
1718
1719 pdstring process::tryToFindExecutable(const pdstring &iprogpath, int pid) {
1720   // This is called by exec, so we might have a valid file path. If so,
1721   // use it... otherwise go to /proc. Helps with exec aliasing problems.
1722
1723   int filedes = open(iprogpath.c_str(), O_RDONLY);
1724   if (filedes != -1) {
1725     close(filedes);
1726     return iprogpath;
1727   }
1728
1729   // We need to dereference the /proc link.
1730   // Case 1: multiple copies of the same file opened with multiple
1731   // pids will not match (and should)
1732   // Case 2: an exec'ed program will have the same /proc path,
1733   // but different program paths
1734   pdstring procpath = pdstring("/proc/") + pdstring(pid) + pdstring("/object/a.out");
1735
1736   // Sure would be nice if we could get the original....
1737
1738   return procpath;
1739 }
1740
1741
1742
1743