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