2 * Copyright (c) 1996 Barton P. Miller
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.
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.
18 * (for other uses, please contact us at paradyn@cs.wisc.edu)
20 * All warranties, including without limitation, any warranty of
21 * merchantability or fitness for a particular purpose, are hereby
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.
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.
42 // $Id: solaris.C,v 1.79 1999/10/29 22:32:32 zandy Exp $
44 #include "dyninstAPI/src/symtab.h"
45 #include "util/h/headers.h"
46 #include "dyninstAPI/src/os.h"
47 #include "dyninstAPI/src/process.h"
48 #include "dyninstAPI/src/pdThread.h"
49 #include "dyninstAPI/src/stats.h"
50 #include "util/h/Types.h"
51 #include <sys/ioctl.h>
53 #include <sys/termios.h>
55 #include "dyninstAPI/src/showerror.h"
56 #include "util/h/pathName.h" // concat_pathname_components()
57 #include "util/h/debugOstream.h"
58 #include "util/h/solarisKludges.h"
60 #if defined (sparc_sun_solaris2_4)
61 #include "dyninstAPI/src/inst-sparc.h"
63 #include "dyninstAPI/src/inst-x86.h"
66 #include "instPoint.h"
68 #include <sys/procfs.h>
75 #define DLOPEN_MODE (RTLD_NOW | RTLD_GLOBAL)
78 extern int ioctl(int, int, ...);
79 extern long sysconf(int);
82 // The following were defined in process.C
83 extern debug_ostream attach_cerr;
84 extern debug_ostream inferiorrpc_cerr;
85 extern debug_ostream shmsample_cerr;
86 extern debug_ostream forkexec_cerr;
87 extern debug_ostream metric_cerr;
88 extern debug_ostream signal_cerr;
91 Define the indices of some registers to be used with pr_reg.
92 These values are different on sparc and x86 platforms.
93 RETVAL_REG: the registers that holds the return value of calls ($o0 on sparc,
95 PC_REG: program counter
96 FP_REG: frame pointer (%i7 on sparc, %ebp on x86)
98 #ifdef sparc_sun_solaris2_4
99 #define RETVAL_REG (R_O0)
100 #define PC_REG (R_PC)
101 #define FP_REG (R_O6)
103 #ifdef i386_unknown_solaris2_5
104 #define RETVAL_REG (EAX)
110 extern bool isValidAddress(process *proc, Address where);
111 extern void generateBreakPoint(instruction &insn);
114 osTraceMe is called after we fork a child process to set
115 a breakpoint on the exit of the exec system call.
116 When /proc is used, this breakpoint **will not** cause a SIGTRAP to
117 be sent to the process. The parent should use PIOCWSTOP to wait for
120 void OS::osTraceMe(void) {
124 sprintf(procName,"/proc/%05d", (int)getpid());
125 int fd = P_open(procName, O_RDWR, 0);
127 fprintf(stderr, "osTraceMe: open failed: %s\n", sys_errlist[errno]);
129 P__exit(-1); // must use _exit here.
132 /* set a breakpoint at the exit of exec/execve */
133 premptyset(&exitSet);
134 praddset(&exitSet, SYS_exec);
135 praddset(&exitSet, SYS_execve);
137 if (ioctl(fd, PIOCSEXIT, &exitSet) < 0) {
138 fprintf(stderr, "osTraceMe: PIOCSEXIT failed: %s\n", sys_errlist[errno]);
140 P__exit(-1); // must use _exit here.
149 // already setup on this FD.
150 // disconnect from controlling terminal
151 void OS::osDisconnect(void) {
152 int ttyfd = open ("/dev/tty", O_RDONLY);
153 ioctl (ttyfd, TIOCNOTTY, NULL);
157 bool process::continueWithForwardSignal(int) {
158 if (-1 == ioctl(proc_fd, PIOCRUN, NULL)) {
159 perror("could not forward signal in PIOCRUN");
166 #ifndef BPATCH_LIBRARY
167 bool process::dumpImage() {return false;}
169 bool process::dumpImage(string imageFileName)
176 string origFile = im->file();
179 // first copy the entire image file
183 command += imageFileName;
184 system(command.string_of());
187 newFd = open(imageFileName.string_of(), O_RDWR, 0);
193 Elf *elfp = elf_begin(newFd, ELF_C_READ, 0);
195 Address baseAddr = 0;
200 Elf_Scn* shstrscnp = 0;
201 Elf_Data* shstrdatap = 0;
204 assert(ehdrp = elf32_getehdr(elfp));
205 assert(((shstrscnp = elf_getscn(elfp, ehdrp->e_shstrndx)) != 0) &&
206 ((shstrdatap = elf_getdata(shstrscnp, 0)) != 0));
207 const char* shnames = (const char *) shstrdatap->d_buf;
209 while ((scn = elf_nextscn(elfp, scn)) != 0) {
212 shdrp = elf32_getshdr(scn);
213 name = (const char *) &shnames[shdrp->sh_name];
214 if (!strcmp(name, ".text")) {
215 offset = shdrp->sh_offset;
216 length = shdrp->sh_size;
217 baseAddr = shdrp->sh_addr;
223 char tempCode[length];
226 bool ret = readTextSpace_((void *) baseAddr, length, tempCode);
232 lseek(newFd, offset, SEEK_SET);
233 write(newFd, tempCode, length);
242 execResult: return the result of an exec system call - true if succesful.
243 The traced processes will stop on exit of an exec system call, just before
244 returning to user code. At this point the return value (errno) is already
245 written to a register, and we need to check if the return value is zero.
247 static inline bool execResult(prstatus_t stat) {
248 return (stat.pr_reg[RETVAL_REG] == 0);
252 wait for inferior processes to terminate or stop.
254 #ifdef BPATCH_LIBRARY
255 int process::waitProcs(int *status, bool block) {
257 int process::waitProcs(int *status) {
259 extern vector<process*> processVec;
261 static struct pollfd fds[OPEN_MAX]; // argument for poll
262 static int selected_fds; // number of selected
263 static int curr; // the current element of fds
265 #ifdef BPATCH_LIBRARY
269 /* Each call to poll may return many selected fds. Since we only report the
270 status of one process per call to waitProcs, we keep the result of the
271 last poll buffered, and simply process an element from the buffer until
272 all of the selected fds in the last poll have been processed.
275 if (selected_fds == 0) {
276 for (unsigned u = 0; u < processVec.size(); u++) {
278 (processVec[u]->status() == running ||
279 processVec[u]->status() == neonatal))
280 fds[u].fd = processVec[u]->proc_fd;
283 fds[u].events = POLLPRI;
287 #ifdef BPATCH_LIBRARY
289 if (block) timeout = INFTIM;
291 selected_fds = poll(fds, processVec.size(), timeout);
293 selected_fds = poll(fds, processVec.size(), 0);
295 if (selected_fds < 0) {
296 fprintf(stderr, "waitProcs: poll failed: %s\n", sys_errlist[errno]);
304 if (selected_fds > 0) {
305 while (fds[curr].revents == 0)
308 // fds[curr] has an event of interest
313 // explicitly initialize "stat" struct (to pacify Purify)
314 // (at least initialize those components which we actually use)
315 stat.pr_flags = 0x0000;
318 stat.pr_reg[RETVAL_REG] = 0;
321 #ifdef BPATCH_LIBRARY
322 if (fds[curr].revents & POLLHUP) {
324 ret = waitpid(processVec[curr]->getPid(), status, 0);
325 } while ((ret < 0) && (errno == EINTR));
327 // This means that the application exited, but was not our child
328 // so it didn't wait around for us to get it's return code. In
329 // this case, we can't know why it exited or what it's return
331 ret = processVec[curr]->getPid();
334 assert(ret == processVec[curr]->getPid());
337 if (ioctl(fds[curr].fd, PIOCSTATUS, &stat) != -1
338 && ((stat.pr_flags & PR_STOPPED) || (stat.pr_flags & PR_ISTOP))) {
339 switch (stat.pr_why) {
341 // return the signal number
342 *status = stat.pr_what << 8 | 0177;
343 ret = processVec[curr]->getPid();
344 #if defined(USES_LIBDYNINSTRT_SO)
345 if (!processVec[curr]->dyninstLibAlreadyLoaded() &&
346 processVec[curr]->wasCreatedViaAttach()) {
347 // make sure we are stopped in the eyes of paradynd - naim
348 bool wasRunning = (processVec[curr]->status() == running);
349 if (processVec[curr]->status() != stopped)
350 processVec[curr]->Stopped();
351 if(processVec[curr]->isDynamicallyLinked()) {
352 processVec[curr]->handleIfDueToSharedObjectMapping();
354 if (processVec[curr]->trapDueToDyninstLib()) {
355 // we need to load libdyninstRT.so.1 - naim
356 processVec[curr]->handleIfDueToDyninstLib();
359 if (!processVec[curr]->continueProc()) assert(0);
364 // exit of a system call.
365 process *p = processVec[curr];
367 if (p->RPCs_waiting_for_syscall_to_complete) {
368 // reset PIOCSEXIT mask
369 inferiorrpc_cerr << "solaris got PR_SYSEXIT!" << endl;
370 assert(p->save_exitset_ptr != NULL);
371 if (-1 == ioctl(p->proc_fd, PIOCSEXIT, p->save_exitset_ptr))
373 delete [] p->save_exitset_ptr;
374 p->save_exitset_ptr = NULL;
376 // fall through on purpose (so status, ret get set)
378 else if (!execResult(stat)) {
379 // a failed exec. continue the process
380 processVec[curr]->continueProc_();
384 *status = SIGTRAP << 8 | 0177;
385 ret = processVec[curr]->getPid();
405 #ifdef BPATCH_LIBRARY
409 return waitpid(0, status, WNOHANG);
414 static char *extract_string_ptr(int procfd, char **ptr) {
415 // we want to return *ptr.
417 if (-1 == lseek(procfd, (long)ptr, SEEK_SET))
421 if (-1 == read(procfd, &result, sizeof(result)))
427 string extract_string(int procfd, const char *inferiorptr) {
428 // assuming inferiorptr points to a null-terminated string in the inferior
429 // process, extract it and return it.
431 if (-1 == lseek(procfd, (long)inferiorptr, SEEK_SET))
437 if (-1 == read(procfd, &buffer, 80))
442 // was there a '\0' anywhere in chars 0 thru 79? If so then
444 for (unsigned lcv=0; lcv < 80; lcv++)
445 if (buffer[lcv] == '\0') {
446 //attach_cerr << "extract_string returning " << result << endl;
452 bool get_ps_stuff(int proc_fd, string &argv0, string &pathenv, string &cwdenv) {
453 // Use ps info to obtain argv[0], PATH, and curr working directory of the
454 // inferior process designated by proc_fd. Writes to argv0, pathenv, cwdenv.
458 // explicitly initialize "the_psinfo" struct (to pacify Purify)
459 // (at least initialize those components which we actually use)
460 the_psinfo.pr_zomb = 0;
461 the_psinfo.pr_argc = 0;
462 the_psinfo.pr_argv = NULL;
463 the_psinfo.pr_envp = NULL;
466 if (-1 == ioctl(proc_fd, PIOCPSINFO, &the_psinfo))
469 if (the_psinfo.pr_zomb)
472 // get argv[0]. It's in the_psinfo.pr_argv[0], but that's a ptr in the inferior
473 // space, so we need to /proc read() it out. Also, the_psinfo.pr_argv is a char **
474 // not a char* so we even need to /proc read() to get a pointer value. Ick.
475 assert(the_psinfo.pr_argv != NULL);
476 char *ptr_to_argv0 = extract_string_ptr(proc_fd, the_psinfo.pr_argv);
477 argv0 = extract_string(proc_fd, ptr_to_argv0);
479 // Get the PWD and PATH environment variables from the application.
480 char **envptr = the_psinfo.pr_envp;
482 // dereference envptr; check for NULL
483 char *env = extract_string_ptr(proc_fd, envptr);
487 string env_value = extract_string(proc_fd, env);
488 if (env_value.prefixed_by("PWD=") || env_value.prefixed_by("CWD=")) {
489 cwdenv = env_value.string_of() + 4; // skip past "PWD=" or "CWD="
490 attach_cerr << "get_ps_stuff: using PWD value of: " << cwdenv << endl;
492 else if (env_value.prefixed_by("PATH=")) {
493 pathenv = env_value.string_of() + 5; // skip past the "PATH="
494 attach_cerr << "get_ps_stuff: using PATH value of: " << pathenv << endl;
504 Open the /proc file correspoding to process pid,
505 set the signals to be caught to be only SIGSTOP and SIGTRAP,
506 and set the kill-on-last-close and inherit-on-fork flags.
508 extern string pd_flavor ;
509 bool process::attach() {
512 // QUESTION: does this attach operation lead to a SIGTRAP being forwarded
513 // to paradynd in all cases? How about when we are attaching to an
514 // already-running process? (Seems that in the latter case, no SIGTRAP
515 // is automatically generated)
517 // step 1) /proc open: attach to the inferior process
518 sprintf(procName,"/proc/%05d", (int)pid);
519 int fd = P_open(procName, O_RDWR, 0);
521 fprintf(stderr, "attach: open failed: %s\n", sys_errlist[errno]);
525 // step 2) /proc PIOCSTRACE: define which signals should be forwarded to daemon
526 // These are (1) SIGSTOP and (2) either SIGTRAP (sparc) or SIGILL (x86), to
527 // implement inferiorRPC completion detection.
532 praddset(&sigs, SIGSTOP);
534 #ifndef i386_unknown_solaris2_5
535 praddset(&sigs, SIGTRAP);
538 #ifdef i386_unknown_solaris2_5
539 praddset(&sigs, SIGILL);
542 if (ioctl(fd, PIOCSTRACE, &sigs) < 0) {
543 fprintf(stderr, "attach: ioctl failed: %s\n", sys_errlist[errno]);
548 // Step 3) /proc PIOCSET:
549 // a) turn on the kill-on-last-close flag (kills inferior with SIGKILL when
550 // the last writable /proc fd closes)
551 // b) turn on inherit-on-fork flag (tracing flags inherited when
552 // child forks) in Paradyn only
553 // c) turn on breakpoint trap pc adjustment (x86 only).
554 // Also, any child of this process will stop at the exit of an exec call.
556 //Tempest, do not need to inherit-on-fork
558 #ifdef BPATCH_LIBRARY
559 /* FIXME: When fork/exec callbacks are implemented for Dyninst, set
560 PR_FORK here, too. It is not set now because otherwise the child
561 would inherit trap-on-exit from exec. With no way for a mutator
562 to handle this stop, the child process would remain stopped
566 if(process::pdFlavor == string("cow"))
567 flags = PR_KLC | PR_BPTADJ;
569 flags = PR_KLC | PR_FORK | PR_BPTADJ;
571 if (ioctl (fd, PIOCSET, &flags) < 0) {
572 fprintf(stderr, "attach: PIOCSET failed: %s\n", sys_errlist[errno]);
579 if (!get_ps_stuff(proc_fd, this->argv0, this->pathenv, this->cwdenv))
585 #if defined(USES_LIBDYNINSTRT_SO)
586 bool process::trapAtEntryPointOfMain()
590 // explicitly initialize "regs" struct (to pacify Purify)
591 // (at least initialize those components which we actually use)
592 for (unsigned r=0; r<(sizeof(regs)/sizeof(regs[0])); r++) regs[r]=0;
595 if (ioctl (proc_fd, PIOCGREG, ®s) != -1) {
596 // is the trap instr at main_brk_addr?
597 if(regs[R_PC] == (int)main_brk_addr){
604 bool process::trapDueToDyninstLib()
606 if (dyninstlib_brk_addr == 0) // not set yet!
611 // explicitly initialize "regs" struct (to pacify Purify)
612 // (at least initialize those components which we actually use)
613 for (unsigned r=0; r<(sizeof(regs)/sizeof(regs[0])); r++) regs[r]=0;
616 if (ioctl (proc_fd, PIOCGREG, ®s) != -1) {
617 // is the trap instr at dyninstlib_brk_addr?
618 if(regs[R_PC] == (int)dyninstlib_brk_addr){
625 void process::handleIfDueToDyninstLib()
627 // rewrite original instructions in the text segment we use for
628 // the inferiorRPC - naim
629 unsigned count = sizeof(savedCodeBuffer);
630 //Address codeBase = getImage()->codeOffset();
632 Address codeBase = (this->findOneFunction("_start"))->addr();
634 writeDataSpace((void *)codeBase, count, (char *)savedCodeBuffer);
637 restoreRegisters(savedRegs);
639 #if defined(i386_unknown_solaris2_5)
640 // restore the stack frame of _start()
641 prgregset_t theIntRegs; theIntRegs = *(prgregset_t *)savedRegs;
642 Address theEBP = theIntRegs[EBP];
644 // this is pretty kludge. if the stack frame of _start is not the right
645 // size, this would break.
646 writeDataSpace ((void*)(theEBP-6*sizeof(int)),6*sizeof(int),savedStackFrame);
653 void process::handleTrapAtEntryPointOfMain()
655 function_base *f_main = findOneFunction("main");
657 Address addr = f_main->addr();
658 // restore original instruction
659 #if defined(sparc_sun_solaris2_4)
660 writeDataSpace((void *)addr, sizeof(instruction), (char *)savedCodeBuffer);
662 writeDataSpace((void *)addr, 2, (char *)savedCodeBuffer);
666 void process::insertTrapAtEntryPointOfMain()
668 function_base *f_main = findOneFunction("main");
670 // we can't instrument main - naim
671 showErrorCallback(108,"main() uninstrumentable");
672 extern void cleanUpAndExit(int);
677 Address addr = f_main->addr();
679 // save original instruction first
680 #if defined(sparc_sun_solaris2_4)
681 readDataSpace((void *)addr, sizeof(instruction), savedCodeBuffer, true);
683 readDataSpace((void *)addr, 2, savedCodeBuffer, true);
685 // and now, insert trap
686 instruction insnTrap;
687 generateBreakPoint(insnTrap);
688 #if defined(sparc_sun_solaris2_4)
689 writeDataSpace((void *)addr, sizeof(instruction), (char *)&insnTrap);
690 #else //x86. have to use SIGILL instead of SIGTRAP
691 writeDataSpace((void *)addr, 2, insnTrap.ptr());
693 main_brk_addr = addr;
696 bool process::dlopenDYNINSTlib() {
697 // we will write the following into a buffer and copy it into the
698 // application process's address space
699 // [....LIBRARY's NAME...|code for DLOPEN]
701 // write to the application at codeOffset. This won't work if we
702 // attach to a running process.
703 //Address codeBase = this->getImage()->codeOffset();
704 // ...let's try "_start" instead
705 Address codeBase = (this->findOneFunction("_start"))->addr();
708 // Or should this be readText... it seems like they are identical
709 // the remaining stuff is thanks to Marcelo's ideas - this is what
710 // he does in NT. The major change here is that we use AST's to
711 // generate code for dlopen.
713 // savedCodeBuffer[BYTES_TO_SAVE] is declared in process.h
714 readDataSpace((void *)codeBase, sizeof(savedCodeBuffer), savedCodeBuffer, true);
716 unsigned char scratchCodeBuffer[BYTES_TO_SAVE];
717 vector<AstNode*> dlopenAstArgs(2);
721 #ifdef BPATCH_LIBRARY /* dyninst API doesn't load libsocket.so.1 */
724 dlopenAstArgs[0] = new AstNode(AstNode::Constant, (void*)0);
725 // library name. We use a scratch value first. We will update this parameter
726 // later, once we determine the offset to find the string - naim
727 dlopenAstArgs[1] = new AstNode(AstNode::Constant, (void*)DLOPEN_MODE); // mode
728 AstNode *dlopenAst = new AstNode("dlopen",dlopenAstArgs);
729 removeAst(dlopenAstArgs[0]);
730 removeAst(dlopenAstArgs[1]);
733 // deadList and deadListSize are defined in inst-sparc.C - naim
734 extern Register deadList[];
735 extern unsigned int deadListSize;
736 registerSpace *dlopenRegSpace = new registerSpace(deadListSize/sizeof(Register),
737 deadList, (unsigned)0, NULL);
738 dlopenRegSpace->resetSpace();
740 #ifndef BPATCH_LIBRARY /* dyninst API doesn't load libsocket.so.1 */
741 dlopenAst->generateCode(this, dlopenRegSpace, (char *)scratchCodeBuffer,
743 writeDataSpace((void *)codeBase, count, (char *)scratchCodeBuffer);
744 // the following seems to be a redundant relic
745 //#if defined(sparc_sun_solaris2_4)
746 // count += sizeof(instruction);
750 // we need to make 2 calls to dlopen: one to load libsocket.so.1 and another
751 // one to load libdyninst.so.1 - naim
753 #ifndef BPATCH_LIBRARY /* since dyninst API didn't create an ast yet */
754 removeAst(dlopenAst); // to avoid memory leaks - naim
756 dlopenAstArgs[0] = new AstNode(AstNode::Constant, (void*)0);
757 // library name. We use a scratch value first. We will update this parameter
758 // later, once we determine the offset to find the string - naim
759 dlopenAstArgs[1] = new AstNode(AstNode::Constant, (void*)DLOPEN_MODE); // mode
760 dlopenAst = new AstNode("dlopen",dlopenAstArgs);
761 removeAst(dlopenAstArgs[0]);
762 removeAst(dlopenAstArgs[1]);
764 Address dyninst_count = 0;
765 dlopenAst->generateCode(this, dlopenRegSpace, (char *)scratchCodeBuffer,
766 dyninst_count, true, true);
767 writeDataSpace((void *)(codeBase+count), dyninst_count, (char *)scratchCodeBuffer);
768 // the following seems to be a redundant relic
769 //#if defined(sparc_sun_solaris2_4)
770 // dyninst_count += sizeof(instruction);
772 count += dyninst_count;
774 instruction insnTrap;
775 generateBreakPoint(insnTrap);
776 #if defined(sparc_sun_solaris2_4)
777 writeDataSpace((void *)(codeBase + count), sizeof(instruction),
779 dyninstlib_brk_addr = codeBase + count;
780 count += sizeof(instruction);
782 writeDataSpace((void *)(codeBase + count), 2, insnTrap.ptr());
783 dyninstlib_brk_addr = codeBase + count;
788 #ifdef BPATCH_LIBRARY /* dyninst API loads a different run-time library */
789 if (getenv("DYNINSTAPI_RT_LIB") != NULL) {
790 strcpy((char*)libname,(char*)getenv("DYNINSTAPI_RT_LIB"));
791 if (access(libname, R_OK)) {
792 string msg = string(libname) + string(" does not exist or cannot be accessed");
793 showErrorCallback(101, msg);
797 string msg = string("Environment variable DYNINSTAPI_RT_LIB is not defined;"
798 " should be set to the pathname of the dyninstAPI_RT runtime library.");
799 showErrorCallback(101, msg);
803 if (getenv("PARADYN_LIB") != NULL) {
804 strcpy((char*)libname,(char*)getenv("PARADYN_LIB"));
805 if (access(libname, R_OK)) {
806 string msg = string(libname) + string(" does not exist or cannot be accessed");
807 showErrorCallback(101, msg);
811 string msg = string("Environment variable PARADYN_LIB has not been defined"
812 " for process") + string(pid);
813 showErrorCallback(101, msg);
818 Address dyninstlib_addr = codeBase + count;
820 writeDataSpace((void *)(codeBase + count), strlen(libname)+1,
822 count += strlen(libname)+1;
823 // we have now written the name of the library after the trap - naim
825 #ifdef BPATCH_LIBRARY /* dyninst API doesn't load libsocket.so.1 */
826 assert(count<=BYTES_TO_SAVE);
827 // The dyninst API doesn't load the socket library
829 char socketname[256];
830 if (getenv("PARADYN_SOCKET_LIB") != NULL) {
831 strcpy((char*)socketname,(char*)getenv("PARADYN_SOCKET_LIB"));
833 strcpy((char*)socketname,(char *)"/usr/lib/libsocket.so.1");
835 Address socketlib_addr = codeBase + count;
836 writeDataSpace((void *)(codeBase + count),
837 strlen(socketname)+1, (caddr_t)socketname);
838 count += strlen(socketname)+1;
839 // we have now written the name of the socket library after the trap - naim
841 assert(count<=BYTES_TO_SAVE);
844 #ifdef BPATCH_LIBRARY /* dyninst API doesn't load libsocket.so.1 */
845 count = 0; // reset count
847 // at this time, we know the offset for the library name, so we fix the
848 // call to dlopen and we just write the code again! This is probably not
849 // very elegant, but it is easy and it works - naim
850 // loading the socket library - naim
851 removeAst(dlopenAst); // to avoid leaking memory
852 //dlopenAstArgs[0] = new AstNode(AstNode::Constant, (void *)(codeBase+count+strlen(libname)+1));
853 dlopenAstArgs[0] = new AstNode(AstNode::Constant, (void *)(socketlib_addr));
854 dlopenAstArgs[1] = new AstNode(AstNode::Constant, (void*)DLOPEN_MODE);
855 dlopenAst = new AstNode("dlopen",dlopenAstArgs);
856 removeAst(dlopenAstArgs[0]);
857 removeAst(dlopenAstArgs[1]);
858 count = 0; // reset count
859 dlopenAst->generateCode(this, dlopenRegSpace, (char *)scratchCodeBuffer,
861 writeDataSpace((void *)codeBase, count, (char *)scratchCodeBuffer);
862 removeAst(dlopenAst);
865 // at this time, we know the offset for the library name, so we fix the
866 // call to dlopen and we just write the code again! This is probably not
867 // very elegant, but it is easy and it works - naim
868 removeAst(dlopenAst); // to avoid leaking memory
869 dlopenAstArgs[0] = new AstNode(AstNode::Constant, (void *)(dyninstlib_addr));
870 dlopenAstArgs[1] = new AstNode(AstNode::Constant, (void*)DLOPEN_MODE);
871 dlopenAst = new AstNode("dlopen",dlopenAstArgs);
872 removeAst(dlopenAstArgs[0]);
873 removeAst(dlopenAstArgs[1]);
874 dyninst_count = 0; // reset count
875 dlopenAst->generateCode(this, dlopenRegSpace, (char *)scratchCodeBuffer,
876 dyninst_count, true, true);
877 writeDataSpace((void *)(codeBase+count), dyninst_count, (char *)scratchCodeBuffer);
878 removeAst(dlopenAst);
879 count += dyninst_count;
882 savedRegs = getRegisters();
883 assert((savedRegs!=NULL) && (savedRegs!=(void *)-1));
884 #if defined(i386_unknown_solaris2_5)
885 // save the stack frame of _start()
886 prgregset_t regs; regs = *(prgregset_t*)savedRegs;
887 Address theEBP = regs[EBP];
889 // this is pretty kludge. if the stack frame of _start is not the right
890 // size, this would break.
891 readDataSpace((void*)(theEBP-6*sizeof(int)),6*sizeof(int), savedStackFrame, true);
893 isLoadingDyninstLib = true;
894 if (!changePC(codeBase,savedRegs)) // this uses the info in "savedRegs"
896 logLine("WARNING: changePC failed in dlopenDYNINSTlib\n");
903 Address process::get_dlopen_addr() const {
905 return(dyn->get_dlopen_addr());
911 bool process::isRunning_() const {
912 // determine if a process is running by doing low-level system checks, as
913 // opposed to checking the 'status_' member vrble. May assume that attach()
914 // has run, but can't assume anything else.
917 // explicitly initialize "theStatus" struct (to pacify Purify)
918 memset(&theStatus, '\0', sizeof(prstatus));
920 if (ioctl(proc_fd, PIOCSTATUS, &theStatus) == -1) {
921 perror("process::isRunning_()");
925 if (theStatus.pr_flags & PR_STOPPED)
931 bool process::attach_() {assert(false); return(false);}
932 bool process::stop_() {assert(false); return(false);}
935 continue a process that is stopped
937 bool process::continueProc_() {
938 ptraceOps++; ptraceOtherOps++;
941 Address pc; // PC at which we are trying to continue
944 // explicitly initialize "flags" struct (to pacify Purify)
945 memset(&flags, '\0', sizeof(flags));
946 // explicitly initialize "stat" struct (to pacify Purify)
947 // (at least initialize those components which we actually use)
948 stat.pr_flags = 0x0000;
953 // a process that receives a stop signal stops twice. We need to run the process
954 // and wait for the second stop. (The first run simply absorbs the stop signal;
955 // the second one does the actual continue.)
956 if (ioctl(proc_fd, PIOCSTATUS, &stat) == -1) return false;
958 if ((0==stat.pr_flags & PR_STOPPED) && (0==stat.pr_flags & PR_ISTOP))
961 if ((stat.pr_flags & PR_STOPPED)
962 && (stat.pr_why == PR_SIGNALLED)
963 && (stat.pr_what == SIGSTOP || stat.pr_what == SIGINT)) {
964 flags.pr_flags = PRSTOP;
965 if (ioctl(proc_fd, PIOCRUN, &flags) == -1) {
966 fprintf(stderr, "continueProc_: PIOCRUN failed: %s\n", sys_errlist[errno]);
969 if (ioctl(proc_fd, PIOCWSTOP, 0) == -1) {
970 fprintf(stderr, "continueProc_: PIOCWSTOP failed: %s\n", sys_errlist[errno]);
974 flags.pr_flags = PRCSIG; // clear current signal
976 // set new program counter
977 //cerr << "continueProc_ doing new currentPC: " << (void*)currentPC_ << endl;
978 flags.pr_vaddr = (caddr_t) currentPC_;
979 flags.pr_flags |= PRSVADDR;
983 pc = (Address)stat.pr_reg[PC_REG];
985 if (! (stoppedInSyscall && pc == postsyscallpc)) {
986 // Continue the process
987 if (ioctl(proc_fd, PIOCRUN, &flags) == -1) {
989 "continueProc_: PIOCRUN 2 failed: %s\n",
995 // We interrupted a sleeping system call at some previous pause
996 // (i.e. stoppedInSyscall is true), we have not restarted that
997 // system call yet, and the current PC is the insn following
998 // the interrupted call. It is time to restart the system
1001 // Note that when we make the process runnable, we ignore
1002 // `flags', set if `hasNewPC' was true in the previous block,
1003 // because we don't want its PC; we want the PC of the system
1004 // call trap, which was saved in `syscallreg'.
1006 sysset_t scentry, scsavedentry;
1011 "NOTE: Continuing a process that was sleeping in a syscall\n");
1015 // Restore the registers
1016 if (0 > ioctl(proc_fd, PIOCSREG, syscallreg)) {
1018 "Can't restart sleeping syscall (PIOCSREG)\n");
1023 // Save current syscall entry traps
1024 if (0 > ioctl(proc_fd, PIOCGENTRY, &scsavedentry)) {
1026 "warn: Can't restart sleeping syscall (PIOCGENTRY)\n");
1031 // Set the process to trap on entry to previously stopped syscall
1032 premptyset(&scentry);
1033 praddset(&scentry, stoppedSyscall);
1034 if (0 > ioctl(proc_fd, PIOCSENTRY, &scentry)) {
1036 "warn: Can't restart sleeping syscall (PIOCSENTRY)\n");
1041 // Continue the process
1042 run.pr_flags = PRCSIG; // Clear current signal
1043 if (0 > ioctl(proc_fd, PIOCRUN, &run)) {
1045 "warn: Can't restart sleeping syscall (PIOCRUN)\n");
1050 // Wait for the process to stop
1051 if (0 > ioctl(proc_fd, PIOCWSTOP, &stat)) {
1053 "warn: Can't restart sleeping syscall (PIOCWSTOP)\n");
1058 // Verify we've stopped at the entry of the call we're trying
1060 if (stat.pr_why != PR_SYSENTRY
1061 || stat.pr_what != stoppedSyscall) {
1063 "warn: Can't restart sleeping syscall (verify)\n");
1068 // Restore the syscall entry traps
1069 if (0 > ioctl(proc_fd, PIOCSENTRY, &scsavedentry)) {
1071 "warn: Can't restart sleeping syscall (PIOCSENTRY)\n");
1077 // Restore the registers again.
1078 // Sun told us to do this, but we don't know why. On the
1079 // SPARC, it doesn't matter -- the system call can be restarted
1080 // whether or not we do this. On the x86, the restart FAILS if
1081 // we do this. So Sun can go sit and spin for all I care.
1082 if (0 > ioctl(proc_fd, PIOCSREG, syscallreg)) {
1084 "Can't restart sleeping syscall (PIOCSREG)\n");
1090 // We are done -- the process is in the kernel for the system
1091 // call, with the right registers values. Make the process
1092 // runnable, restoring its previously blocked signals.
1093 stoppedInSyscall = false;
1094 run.pr_sighold = sighold;
1095 run.pr_flags = PRSHOLD;
1096 if (0 > ioctl(proc_fd, PIOCRUN, &run)) {
1098 "Can't restart sleeping syscall (PIOCRUN)\n");
1106 #ifdef BPATCH_LIBRARY
1108 terminate execution of a process
1110 bool process::terminateProc_()
1112 long flags = PR_KLC;
1113 if (ioctl (proc_fd, PIOCSET, &flags) < 0)
1122 #if defined(USES_DYNAMIC_INF_HEAP)
1123 static const Address lowest_addr = 0x0;
1124 void inferiorMallocConstraints(Address near, Address &lo, Address &hi)
1126 lo = region_lo(near);
1127 hi = region_hi(near);
1130 // ALERT: could be specific to SPARC
1131 void inferiorMallocAlign(unsigned &size)
1133 size = (size + 0x1f) & ~0x1f;
1138 pause a process that is running
1140 bool process::pause_() {
1141 ptraceOps++; ptraceOtherOps++;
1144 sysset_t scexit, scsavedexit;
1145 prstatus_t prstatus;
1147 // /proc PIOCSTOP: direct all LWPs to stop, _and_ wait for them to stop.
1148 ioctl_ret = ioctl(proc_fd, PIOCSTOP, &prstatus);
1149 if (ioctl_ret == -1) {
1151 "warn : process::pause_ use ioctl to send PICOSTOP returns error : errno = %i\n", errno);
1152 perror("warn : process::pause_ ioctl PICOSTOP: ");
1157 // Determine if the process was in a system call when we stopped it.
1158 if (! (prstatus.pr_why == PR_REQUESTED
1159 && prstatus.pr_syscall != 0
1160 && (prstatus.pr_flags & PR_ASLEEP))) {
1161 // The process was not in a system call. We're done.
1165 // We stopped a process that it is a system call. We abort the
1166 // system call, so that the process can execute an inferior RPC. We
1167 // save the process state as it was at the ENTRY of the system call,
1168 // so that the system call can be restarted when we continue the
1169 // process. Note: this code does not deal with multiple LWPs.
1171 // We do not expect to recursively interrupt system calls. We could
1172 // probably handle it by keeping a stack of system call state. But
1173 // we haven't yet seen any reason to have this functionality.
1174 assert(!stoppedInSyscall);
1176 // 1. Save the syscall number, registers, and blocked signals
1177 stoppedInSyscall = true;
1178 stoppedSyscall = prstatus.pr_syscall;
1179 memcpy(syscallreg, prstatus.pr_reg, sizeof(prstatus.pr_reg));
1180 sighold = prstatus.pr_sighold;
1181 #ifdef i386_unknown_solaris2_5
1182 // From Roger A. Faulkner at Sun (email unknown), 6/29/1997:
1184 // On Intel and PowerPC machines, the system call trap instruction
1185 // leaves the PC (program counter, instruction pointer) referring to
1186 // the instruction that follows the system call trap instruction.
1187 // On Sparc machines, the system call trap instruction leaves %pc
1188 // referring to the system call trap instruction itself (the
1189 // operating system increments %pc on exit from the system call).
1191 // We have to reset the PC back to the system call trap instruction
1192 // on Intel and PowerPC machines.
1194 // This is 7 on Intel, 4 on PowerPC.
1196 // Note: On x86/Linux this should probably be 2 bytes, because Linux
1197 // uses "int" to trap, not lcall.
1199 syscallreg[PC_REG] -= 7;
1202 // 2. Abort the system call
1204 // Save current syscall exit traps
1205 if (0 > ioctl(proc_fd, PIOCGEXIT, &scsavedexit)) {
1207 "warn: Can't get status (PIOCGEXIT) of paused process\n");
1212 // Set process to trap on exit from this system call
1213 premptyset(&scexit);
1214 praddset(&scexit, stoppedSyscall);
1215 if (0 > ioctl(proc_fd, PIOCSEXIT, &scexit)) {
1217 "warn: Can't step paused process out of syscall (PIOCSEXIT)\n");
1222 // Continue, aborting this system call and blocking all sigs except
1223 // those needed by DynInst.
1224 sigfillset(&run.pr_sighold);
1225 sigdelset(&run.pr_sighold, SIGTRAP);
1226 sigdelset(&run.pr_sighold, SIGILL);
1227 run.pr_flags = PRSABORT|PRSHOLD;
1228 if (0 > ioctl(proc_fd, PIOCRUN, &run)) {
1230 "warn: Can't step paused process out of syscall (PIOCRUN)\n");
1236 // Wait for it to stop (at exit of aborted syscall)
1237 if (0 > ioctl(proc_fd, PIOCWSTOP, &prstatus)) {
1239 "warn: Can't step paused process out of syscall (PIOCWSTOP)\n");
1244 // Note: We assume that is always safe to restart the call after
1245 // aborting it. We are wrong if it turns out that some
1246 // interruptible system call can make partial progress before we
1248 // We think this is impossible because the proc manpage says EINTR
1249 // would be returned to the process if we didn't trap the syscall
1250 // exit, and the manpages for interruptible system calls say an
1251 // EINTR return value means no progress was made.
1252 // If we are wrong, this is probably the place to decide whether
1253 // and/or how the syscall should be restarted later.
1255 // Verify that we're stopped in the right place
1256 if (((prstatus.pr_flags & (PR_STOPPED|PR_ISTOP))
1257 != (PR_STOPPED|PR_ISTOP))
1258 || prstatus.pr_why != PR_SYSEXIT
1259 || prstatus.pr_syscall != stoppedSyscall) {
1261 "warn: Can't step paused process out of syscall (Verify)\n");
1266 // Reset the syscall exit traps
1267 if (0 > ioctl(proc_fd, PIOCSEXIT, &scsavedexit)) {
1269 "warn: Can't step paused process out of syscall (PIOCSEXIT)\n");
1274 // Remember the current PC. When we continue the process at this PC
1275 // we will restart the system call.
1276 postsyscallpc = (Address) prstatus.pr_reg[PC_REG];
1279 "NOTE: paused the mutatee while it was sleeping in a system call\n");
1285 close the file descriptor for the file associated with a process
1287 bool process::detach_() {
1292 #ifdef BPATCH_LIBRARY
1294 detach from thr process, continuing its execution if the parameter "cont"
1297 bool process::API_detach_(const bool cont)
1299 // Remove the breakpoint that we put in to detect loading and unloading of
1300 // shared libraries.
1301 // XXX We might want to move this into some general cleanup routine for the
1302 // dynamic_linking object.
1304 dyn->unset_r_brk_point(this);
1307 // Reset the kill-on-close flag, and the run-on-last-close flag if necessary
1308 long flags = PR_KLC;
1309 if (!cont) flags |= PR_RLC;
1310 if (ioctl (proc_fd, PIOCRESET, &flags) < 0) {
1311 fprintf(stderr, "detach: PIOCRESET failed: %s\n", sys_errlist[errno]);
1315 // Set the run-on-last-close-flag if necessary
1318 if (ioctl (proc_fd, PIOCSET, &flags) < 0) {
1319 fprintf(stderr, "detach: PIOCSET failed: %s\n", sys_errlist[errno]);
1327 if (ioctl(proc_fd, PIOCSTRACE, &sigs) < 0) {
1328 fprintf(stderr, "detach: PIOCSTRACE failed: %s\n", sys_errlist[errno]);
1332 if (ioctl(proc_fd, PIOCSHOLD, &sigs) < 0) {
1333 fprintf(stderr, "detach: PIOCSHOLD failed: %s\n", sys_errlist[errno]);
1339 premptyset(&faults);
1340 if (ioctl(proc_fd, PIOCSFAULT, &faults) < 0) {
1341 fprintf(stderr, "detach: PIOCSFAULT failed: %s\n", sys_errlist[errno]);
1347 premptyset(&syscalls);
1348 if (ioctl(proc_fd, PIOCSENTRY, &syscalls) < 0) {
1349 fprintf(stderr, "detach: PIOCSENTRY failed: %s\n", sys_errlist[errno]);
1353 if (ioctl(proc_fd, PIOCSEXIT, &syscalls) < 0) {
1354 fprintf(stderr, "detach: PIOCSEXIT failed: %s\n", sys_errlist[errno]);
1364 bool process::dumpCore_(const string coreName)
1368 sprintf(command, "gcore %d 2> /dev/null; mv core.%d %s", getPid(), getPid(),
1369 coreName.string_of());
1378 bool process::writeTextWord_(caddr_t inTraced, int data) {
1379 // cerr << "writeTextWord @ " << (void *)inTraced << endl; cerr.flush();
1380 return writeDataSpace_(inTraced, sizeof(int), (caddr_t) &data);
1383 bool process::writeTextSpace_(void *inTraced, u_int amount, const void *inSelf) {
1384 // cerr << "writeTextSpace pid=" << getPid() << ", @ " << (void *)inTraced << " len=" << amount << endl; cerr.flush();
1385 return writeDataSpace_(inTraced, amount, inSelf);
1388 #ifdef BPATCH_SET_MUTATIONS_ACTIVE
1389 bool process::readTextSpace_(void *inTraced, u_int amount, const void *inSelf) {
1390 return readDataSpace_(inTraced, amount, const_cast<void *>(inSelf));
1394 bool process::writeDataSpace_(void *inTraced, u_int amount, const void *inSelf) {
1395 ptraceOps++; ptraceBytes += amount;
1397 // cerr << "process::writeDataSpace_ pid " << getPid() << " writing " << amount << " bytes at loc " << inTraced << endl;
1399 if (lseek(proc_fd, (off_t)inTraced, SEEK_SET) != (off_t)inTraced)
1401 return (write(proc_fd, inSelf, amount) == (int)amount);
1404 bool process::readDataSpace_(const void *inTraced, u_int amount, void *inSelf) {
1405 ptraceOps++; ptraceBytes += amount;
1406 if((lseek(proc_fd, (off_t)inTraced, SEEK_SET)) != (off_t)inTraced) {
1407 printf("error in lseek addr = 0x%lx amount = %d\n",
1408 (Address)inTraced,amount);
1411 return (read(proc_fd, inSelf, amount) == (int)amount);
1414 bool process::loopUntilStopped() {
1420 // TODO -- only call getrusage once per round
1421 static struct rusage *get_usage_data() {
1426 #ifndef BPATCH_LIBRARY
1428 float OS::compute_rusage_cpu() {
1432 float OS::compute_rusage_sys() {
1436 float OS::compute_rusage_min() {
1439 float OS::compute_rusage_maj() {
1443 float OS::compute_rusage_swap() {
1446 float OS::compute_rusage_io_in() {
1449 float OS::compute_rusage_io_out() {
1452 float OS::compute_rusage_msg_send() {
1455 float OS::compute_rusage_msg_recv() {
1458 float OS::compute_rusage_sigs() {
1461 float OS::compute_rusage_vol_cs() {
1464 float OS::compute_rusage_inv_cs() {
1470 int getNumberOfCPUs()
1472 // _SC_NPROCESSORS_CONF is the number of processors configured in the
1473 // system and _SC_NPROCESSORS_ONLN is the number of those processors that
1476 numberOfCPUs = (int) sysconf(_SC_NPROCESSORS_ONLN);
1478 return(numberOfCPUs);
1483 // getActiveFrame(): populate Frame object using toplevel frame
1484 void Frame::getActiveFrame(process *p)
1488 memset(&status, 0, sizeof(prstatus_t));
1491 int proc_fd = p->getProcFileDescriptor();
1492 if (ioctl(proc_fd, PIOCSTATUS, &status) != -1) {
1493 #if defined(MT_THREAD)
1494 lwp_id_ = status.pr_who;
1496 fp_ = status.pr_reg[FP_REG];
1497 pc_ = status.pr_reg[PC_REG];
1501 #if defined(MT_THREAD)
1502 // It is the caller's responsibility to do a "delete [] (*IDs)"
1503 bool process::getLWPIDs(int** IDs) {
1505 prstatus_t the_psinfo;
1506 if (-1 != ioctl(proc_fd, PIOCSTATUS, &the_psinfo)) {
1507 nlwp = the_psinfo.pr_nlwp ;
1508 id_t *id_p = new id_t [nlwp+1] ;
1509 if (-1 != ioctl(proc_fd, PIOCLWPIDS, id_p)) {
1510 *IDs = new int [nlwp+1];
1513 (*IDs)[i] = (int) id_p[i];
1514 } while (id_p[i++]);
1522 bool process::getLWPFrame(int lwp_id, Address* fp, Address *pc) {
1524 int lwp_fd = ioctl(proc_fd, PIOCOPENLWP, &(lwp_id));
1526 cerr << "process::getLWPFrame, cannot get lwp_fd" << endl ;
1529 if (-1 != ioctl(lwp_fd, PIOCGREG, ®s)) {
1539 Frame::Frame(pdThread* thr) {
1545 long l3; //g2, g3, g4
1555 process* proc = thr->get_proc();
1557 if (thr->get_start_pc() &&
1558 proc->readDataSpace((caddr_t) thr->get_resumestate_p(),
1559 sizeof(resumestate_t), (caddr_t) &rs, false)) {
1566 #ifdef sparc_sun_solaris2_4
1568 Frame Frame::getCallerFrameNormal(process *p) const
1572 // explicitly initialize "regs" struct (to pacify Purify)
1573 // (at least initialize those components which we actually use)
1574 for (unsigned r=0; r<(sizeof(regs)/sizeof(regs[0])); r++) regs[r]=0;
1578 function_base *func = p->findFunctionIn(pc_);
1580 if (func->hasNoStackFrame()) { // formerly "isLeafFunc()"
1581 int proc_fd = p->getProcFileDescriptor();
1582 if (ioctl(proc_fd, PIOCGREG, ®s) != -1) {
1584 ret.pc_ = regs[R_O7] + 8;
1585 ret.fp_ = fp_; // frame pointer unchanged
1593 // For the sparc, register %i7 is the return address - 8 and the fp is
1594 // register %i6. These registers can be located in %fp+14*5 and
1595 // %fp+14*4 respectively, but to avoid two calls to readDataSpace,
1596 // we bring both together (i.e. 8 bytes of memory starting at %fp+14*4
1598 // These values are copied to the stack when the application is paused,
1599 // so we are assuming that the application is paused at this point
1606 if (p->readDataSpace((caddr_t)(fp_ + 56), 2*sizeof(int),
1607 (caddr_t)&addrs, true))
1611 ret.pc_ = addrs.rtn + 8;
1615 return Frame(); // zero frame
1618 #if defined(MT_THREAD)
1619 Frame Frame::getCallerFrameThread(process *p) const
1621 Frame ret; // zero frame
1623 ret.thread_ = thread_;
1625 // TODO: special handling for uppermost/leaf frame?
1629 // explicitly initialize "regs" struct (to pacify Purify)
1630 // (at least initialize those components which we actually use)
1631 for (unsigned r=0; r<(sizeof(regs)/sizeof(regs[0])); r++) regs[r]=0;
1635 func = this->findFunctionIn(pc_);
1637 if (func->hasNoStackFrame()) { // formerly "isLeafFunc()"
1638 int proc_fd = p->getProcFileDescriptor();
1639 if (ioctl(proc_fd, PIOCGREG, ®s) != -1) {
1640 ret.pc_ = regs[R_O7] + 8;
1649 // For the sparc, register %i7 is the return address - 8 and the fp is
1650 // register %i6. These registers can be located in %fp+14*5 and
1651 // %fp+14*4 respectively, but to avoid two calls to readDataSpace,
1652 // we bring both together (i.e. 8 bytes of memory starting at %fp+14*4
1654 // These values are copied to the stack when the application is paused,
1655 // so we are assuming that the application is paused at this point
1662 if (p->readDataSpace((caddr_t)(fp_ + 56), sizeof(int)*2,
1663 (caddr_t)&addrs, true))
1666 ret.pc_ = addrs.rtn + 8;
1672 Frame Frame::getCallerFrameLWP(process *p) const
1674 Frame ret; // zero frame
1675 ret.lwp_id_ = lwp_id_;
1676 ret.thread_ = NULL ;
1680 // explicitly initialize "regs" struct (to pacify Purify)
1681 // (at least initialize those components which we actually use)
1682 for (unsigned r=0; r<(sizeof(regs)/sizeof(regs[0])); r++) regs[r]=0;
1686 function_base *func = p->findFunctionIn(pc_);
1688 if (func->hasNoStackFrame()) { // formerly "isLeafFunc()"
1689 int proc_fd = p->getProcFileDescriptor();
1690 int lwp_fd = ioctl(proc_fd, PIOCOPENLWP, &(lwp_id_));
1692 cerr << "process::getCallerFrameLWP, cannot get lwp_fd" << endl ;
1693 return Frame(); // zero frame
1695 if (ioctl(lwp_fd, PIOCGREG, ®s) != -1) {
1696 ret.pc_ = regs[R_O7] + 8;
1697 ret.fp_ = fp_; // frame pointer unchanged
1707 // For the sparc, register %i7 is the return address - 8 and the fp is
1708 // register %i6. These registers can be located in %fp+14*5 and
1709 // %fp+14*4 respectively, but to avoid two calls to readDataSpace,
1710 // we bring both together (i.e. 8 bytes of memory starting at %fp+14*4
1712 // These values are copied to the stack when the application is paused,
1713 // so we are assuming that the application is paused at this point
1720 if (p->readDataSpace((caddr_t)(fp_ + 56), 2*sizeof(int)*2,
1721 (caddr_t)&addrs, true))
1724 ret.pc_ = addrs.rtn + 8;
1729 This operation applies only to SPARC machines. p is a
1730 pointer to a gwindows_t structure, defined in <sys/reg.h>,
1731 that is filled with the contents of those SPARC register
1732 windows that could not be stored on the stack when the lwp
1733 stopped. Conditions under which register windows are not
1734 stored on the stack are: the stack pointer refers to
1735 nonexistent process memory or the stack pointer is improp-
1736 erly aligned. If the specific or chosen lwp is not
1737 stopped, the operation returns undefined values.
1746 time64 process::getInferiorProcessCPUtime(int lwp_id) {
1747 // returns user time from the u or proc area of the inferior process, which in
1748 // turn is presumably obtained by mmapping it (sunos) or by using a /proc ioctl
1749 // to obtain it (solaris). It must not stop the inferior process in order
1750 // to obtain the result, nor can it assue that the inferior has been stopped.
1751 // The result MUST be "in sync" with rtinst's DYNINSTgetCPUtime().
1753 // We use the PIOCUSAGE /proc ioctl
1755 // Other /proc ioctls that should work too: PIOCPSINFO
1756 // and the lower-level PIOCGETPR and PIOCGETU which return copies of the proc
1757 // and u areas, respectively.
1758 // PIOCSTATUS does _not_ work because its results are not in sync
1759 // with DYNINSTgetCPUtime
1764 #if defined(MT_THREAD)
1766 // we need to get the CPU time per LWP to be in sync with gethrvtime - naim
1767 int lwp_fd = ioctl(proc_fd, PIOCOPENLWP, &(lwp_id));
1769 sprintf(errorLine,"Cannot read CPU time of inferior process PIOCOPENLWP, lwp_id = %d\n",
1774 if (ioctl(lwp_fd, PIOCUSAGE, &theUsage) == -1) {
1775 perror("could not read CPU time of inferior process PIOCUSAGE");
1778 // we only use pr_utime in here to be in sync with gethrvtime - naim
1779 result = PDYN_mulMillion(theUsage.pr_utime.tv_sec); // sec to usec
1780 result += PDYN_div1000(theUsage.pr_utime.tv_nsec); // nsec to usec
1785 // explicitly initialize "theUsage" struct (to pacify Purify)
1786 memset(&theUsage, '\0', sizeof(prusage_t));
1788 // compute the CPU timer for the whole process
1789 if (ioctl(proc_fd, PIOCUSAGE, &theUsage) == -1) {
1790 perror("could not read CPU time of inferior PIOCUSAGE");
1793 result = PDYN_mulMillion(theUsage.pr_utime.tv_sec); // sec to usec
1794 result += PDYN_div1000(theUsage.pr_utime.tv_nsec); // nsec to usec
1798 // explicitly initialize "theUsage" struct (to pacify Purify)
1799 memset(&theUsage, '\0', sizeof(prusage_t));
1802 if (ioctl(proc_fd, PIOCUSAGE, &theUsage) == -1) {
1803 perror("could not read CPU time of inferior PIOCUSAGE");
1806 result = PDYN_mulMillion(theUsage.pr_utime.tv_sec); // sec to usec
1807 result += PDYN_div1000(theUsage.pr_utime.tv_nsec); // nsec to usec
1809 if (result<previous) {
1810 // time shouldn't go backwards, but we have seen this happening
1811 // before, so we better check it just in case - naim 5/30/97
1812 logLine("********* time going backwards in paradynd **********\n");
1823 void *process::getRegisters() {
1824 // Astonishingly, this routine can be shared between solaris/sparc and
1825 // solaris/x86. All hail /proc!!!
1827 // assumes the process is stopped (/proc requires it)
1828 assert(status_ == stopped);
1830 prgregset_t theIntRegs;
1832 // explicitly initialize "theIntRegs" struct (to pacify Purify)
1833 // (at least initialize those components which we actually use)
1834 for (unsigned r=0; r<(sizeof(theIntRegs)/sizeof(theIntRegs[0])); r++) theIntRegs[r]=0;
1837 if (ioctl(proc_fd, PIOCGREG, &theIntRegs) == -1) {
1838 perror("process::getRegisters PIOCGREG");
1839 if (errno == EBUSY) {
1840 cerr << "It appears that the process was not stopped in the eyes of /proc" << endl;
1847 prfpregset_t theFpRegs;
1849 if (ioctl(proc_fd, PIOCGFPREG, &theFpRegs) == -1) {
1850 perror("process::getRegisters PIOCGFPREG");
1852 cerr << "It appears that the process was not stopped in the eyes of /proc" << endl;
1853 else if (errno == EINVAL)
1854 // what to do in this case? Probably shouldn't even do a print, right?
1855 // And it certainly shouldn't be an error, right?
1856 // But I wonder if any sparcs out there really don't have floating point.
1857 cerr << "It appears that this machine doesn't have floating-point instructions" << endl;
1862 const int numbytesPart1 = sizeof(prgregset_t);
1863 const int numbytesPart2 = sizeof(prfpregset_t);
1864 assert(numbytesPart1 % 4 == 0);
1865 assert(numbytesPart2 % 4 == 0);
1867 void *buffer = new char[numbytesPart1 + numbytesPart2];
1870 memcpy(buffer, &theIntRegs, sizeof(theIntRegs));
1871 memcpy((char *)buffer + sizeof(theIntRegs), &theFpRegs, sizeof(theFpRegs));
1876 bool process::executingSystemCall() {
1879 // explicitly initialize "theStatus" struct (to pacify Purify)
1880 // (at least initialize those components which we actually use)
1881 theStatus.pr_syscall = 0;
1884 if (ioctl(proc_fd, PIOCSTATUS, &theStatus) != -1) {
1885 if (theStatus.pr_syscall > 0) {
1886 inferiorrpc_cerr << "pr_syscall=" << theStatus.pr_syscall << endl;
1893 bool process::changePC(Address addr, const void *savedRegs) {
1894 assert(status_ == stopped);
1896 // make a copy of the registers (on purpose)
1897 prgregset_t theIntRegs;
1898 theIntRegs = *(prgregset_t*)const_cast<void*>(savedRegs);
1900 theIntRegs[R_PC] = addr; // PC (sparc), EIP (x86)
1901 #ifdef R_nPC // true for sparc, not for x86
1902 theIntRegs[R_nPC] = addr + 4;
1905 if (ioctl(proc_fd, PIOCSREG, &theIntRegs) == -1) {
1906 perror("process::changePC PIOCSREG failed");
1908 cerr << "It appears that the process wasn't stopped in the eyes of /proc" << endl;
1915 bool process::changePC(Address addr) {
1916 assert(status_ == stopped); // /proc will require this
1918 prgregset_t theIntRegs;
1919 if (ioctl(proc_fd, PIOCGREG, &theIntRegs) == -1) {
1920 perror("process::changePC PIOCGREG");
1921 if (errno == EBUSY) {
1922 cerr << "It appears that the process wasn't stopped in the eyes of /proc" << endl;
1928 theIntRegs[R_PC] = addr;
1930 theIntRegs[R_nPC] = addr + 4;
1933 if (ioctl(proc_fd, PIOCSREG, &theIntRegs) == -1) {
1934 perror("process::changePC PIOCSREG");
1935 if (errno == EBUSY) {
1936 cerr << "It appears that the process wasn't stopped in the eyes of /proc" << endl;
1945 bool process::restoreRegisters(void *buffer) {
1946 // The fact that this routine can be shared between solaris/sparc and
1947 // solaris/x86 is just really, really cool. /proc rules!
1949 assert(status_ == stopped); // /proc requires it
1951 prgregset_t theIntRegs; theIntRegs = *(prgregset_t *)buffer;
1952 prfpregset_t theFpRegs = *(prfpregset_t *)((char *)buffer + sizeof(theIntRegs));
1954 if (ioctl(proc_fd, PIOCSREG, &theIntRegs) == -1) {
1955 perror("process::restoreRegisters PIOCSREG failed");
1956 if (errno == EBUSY) {
1957 cerr << "It appears that the process was not stopped in the eyes of /proc" << endl;
1963 if (ioctl(proc_fd, PIOCSFPREG, &theFpRegs) == -1) {
1964 perror("process::restoreRegisters PIOCSFPREG failed");
1965 if (errno == EBUSY) {
1966 cerr << "It appears that the process was not stopped in the eyes of /proc" << endl;
1975 #ifdef i386_unknown_solaris2_5
1977 Frame Frame::getCallerFrameNormal(process *p) const
1980 // for the x86, the frame-pointer (EBP) points to the previous frame-pointer,
1981 // and the saved return address is in EBP-4.
1988 if (p->readDataSpace((caddr_t)(fp_), 2*sizeof(int),
1989 (caddr_t)&addrs, true))
1993 ret.pc_ = addrs.rtn;
1997 return Frame(); // zero frame
2002 #ifdef i386_unknown_solaris2_5
2003 // ******** TODO **********
2004 bool process::needToAddALeafFrame(Frame , Address &) {
2010 // needToAddALeafFrame: returns true if the between the current frame
2011 // and the next frame there is a leaf function (this occurs when the
2012 // current frame is the signal handler and the function that was executing
2013 // when the sighandler was called is a leaf function)
2014 bool process::needToAddALeafFrame(Frame current_frame, Address &leaf_pc){
2016 // check to see if the current frame is the signal handler
2017 Address frame_pc = current_frame.getPC();
2018 Address sig_addr = 0;
2019 const image *sig_image = (signal_handler->file())->exec();
2020 if(getBaseAddress(sig_image, sig_addr)){
2021 sig_addr += signal_handler->getAddress(0);
2023 sig_addr = signal_handler->getAddress(0);
2025 u_int sig_size = signal_handler->size();
2026 if(signal_handler&&(frame_pc >= sig_addr)&&(frame_pc < (sig_addr+sig_size))){
2027 // get the value of the saved PC: this value is stored in the address
2028 // specified by the value in register i2 + 44. Register i2 must contain
2029 // the address of some struct that contains, among other things, the
2032 int fp = current_frame.getFP();
2033 if (readDataSpace((caddr_t)(fp+40),sizeof(u_int),(caddr_t)®_i2,true)){
2034 if (readDataSpace((caddr_t) (reg_i2+44), sizeof(int),
2035 (caddr_t) &leaf_pc,true)){
2036 // if the function is a leaf function return true
2037 function_base *func = findFunctionIn(leaf_pc);
2038 if(func && func->hasNoStackFrame()) { // formerly "isLeafFunc()"
2048 string process::tryToFindExecutable(const string &iprogpath, int pid) {
2049 // returns empty string on failure.
2050 // Otherwise, returns a full-path-name for the file. Tries every
2051 // trick to determine the full-path-name, even though "progpath" may be
2052 // unspecified (empty string).
2054 // Remember, we can always return the empty string...no need to
2055 // go nuts writing the world's most complex algorithm.
2057 attach_cerr << "welcome to tryToFindExecutable; progpath=" << iprogpath << ", pid=" << pid << endl;
2059 const string progpath = expand_tilde_pathname(iprogpath);
2061 // Trivial case: if "progpath" is specified and the file exists then nothing needed
2062 if (exists_executable(progpath)) {
2063 attach_cerr << "tryToFindExecutable succeeded immediately, returning "
2064 << progpath << endl;
2068 attach_cerr << "tryToFindExecutable failed on filename " << progpath << endl;
2071 sprintf(buffer, "/proc/%05d", pid);
2072 int procfd = open(buffer, O_RDONLY, 0);
2074 attach_cerr << "tryToFindExecutable failed since open of /proc failed" << endl;
2077 attach_cerr << "tryToFindExecutable: opened /proc okay" << endl;
2079 string argv0, path, cwd;
2080 if (get_ps_stuff(procfd, argv0, path, cwd)) {
2081 // the following routine is implemented in the util lib.
2083 if (executableFromArgv0AndPathAndCwd(result, argv0, path, cwd)) {
2084 (void)close(procfd);
2089 attach_cerr << "tryToFindExecutable: giving up" << endl;
2091 (void)close(procfd);
2095 bool process::set_breakpoint_for_syscall_completion() {
2096 /* Can assume: (1) process is paused and (2) in a system call.
2097 We want to set a TRAP for the syscall exit, and do the
2098 inferiorRPC at that time. We'll use /proc PIOCSEXIT.
2099 Returns true iff breakpoint was successfully set. */
2101 sysset_t save_exitset;
2102 if (-1 == ioctl(proc_fd, PIOCGEXIT, &save_exitset))
2105 sysset_t new_exit_set;
2106 prfillset(&new_exit_set);
2107 if (-1 == ioctl(proc_fd, PIOCSEXIT, &new_exit_set))
2110 assert(save_exitset_ptr == NULL);
2111 save_exitset_ptr = new sysset_t;
2112 memcpy(save_exitset_ptr, &save_exitset, sizeof(save_exitset));
2117 void process::clear_breakpoint_for_syscall_completion() { return; }
2119 Address process::read_inferiorRPC_result_register(Register) {
2121 prgregset_t theIntRegs;
2123 // explicitly initialize "theIntRegs" struct (to pacify Purify)
2124 for (unsigned r=0; r<(sizeof(theIntRegs)/sizeof(theIntRegs[0])); r++)
2128 if (-1 == ioctl(proc_fd, PIOCGREG, &theIntRegs)) {
2129 perror("process::read_inferiorRPC_result_register PIOCGREG");
2130 if (errno == EBUSY) {
2131 cerr << "It appears that the process was not stopped in the eyes of /proc" << endl;
2134 return 0; // assert(false)?
2137 // on x86, the result is always stashed in %EAX; on sparc, it's always %o0.
2138 // In neither case do we need the argument of this fn.
2139 #ifdef i386_unknown_solaris2_5
2140 return theIntRegs[EAX];
2142 return theIntRegs[R_O0];
2146 void print_read_error_info(const relocationEntry entry,
2147 pd_Function *&target_pdf, Address base_addr) {
2149 sprintf(errorLine, " entry : target_addr 0x%lx\n",
2150 entry.target_addr());
2152 sprintf(errorLine, " rel_addr 0x%lx\n", entry.rel_addr());
2154 sprintf(errorLine, " name %s\n", (entry.name()).string_of());
2158 sprintf(errorLine, " target_pdf : symTabName %s\n",
2159 (target_pdf->symTabName()).string_of());
2161 sprintf(errorLine , " prettyName %s\n",
2162 (target_pdf->symTabName()).string_of());
2164 sprintf(errorLine , " size %i\n",
2165 target_pdf->size());
2167 sprintf(errorLine , " addr 0x%lx\n",
2168 target_pdf->addr());
2172 sprintf(errorLine, " base_addr 0x%lx\n", base_addr);
2176 // hasBeenBound: returns true if the runtime linker has bound the
2177 // function symbol corresponding to the relocation entry in at the address
2178 // specified by entry and base_addr. If it has been bound, then the callee
2179 // function is returned in "target_pdf", else it returns false.
2180 bool process::hasBeenBound(const relocationEntry entry,
2181 pd_Function *&target_pdf, Address base_addr) {
2183 // TODO: the x86 and sparc versions should really go in seperate files
2184 #if defined(i386_unknown_solaris2_5)
2186 if (status() == exited) return false;
2188 // if the relocationEntry has not been bound yet, then the value
2189 // at rel_addr is the address of the instruction immediately following
2190 // the first instruction in the PLT entry (which is at the target_addr)
2191 // The PLT entries are never modified, instead they use an indirrect
2192 // jump to an address stored in the _GLOBAL_OFFSET_TABLE_. When the
2193 // function symbol is bound by the runtime linker, it changes the address
2194 // in the _GLOBAL_OFFSET_TABLE_ corresponding to the PLT entry
2196 Address got_entry = entry.rel_addr() + base_addr;
2197 Address bound_addr = 0;
2198 if(!readDataSpace((const void*)got_entry, sizeof(Address),
2199 &bound_addr, true)){
2200 sprintf(errorLine, "read error in process::hasBeenBound "
2201 "addr 0x%lx, pid=%d\n (readDataSpace returns 0)",
2204 print_read_error_info(entry, target_pdf, base_addr);
2208 if( !( bound_addr == (entry.target_addr()+6+base_addr)) ) {
2209 // the callee function has been bound by the runtime linker
2210 // find the function and return it
2211 target_pdf = findpdFunctionIn(bound_addr);
2220 // if the relocationEntry has not been bound yet, then the second instr
2221 // in this PLT entry branches to the fist PLT entry. If it has been
2222 // bound, then second two instructions of the PLT entry have been changed
2223 // by the runtime linker to jump to the address of the function.
2224 // Here is an example:
2225 // before binding after binding
2226 // -------------- -------------
2227 // sethi %hi(0x15000), %g1 sethi %hi(0x15000), %g1
2228 // b,a <_PROCEDURE_LINKAGE_TABLE_> sethi %hi(0xef5eb000), %g1
2229 // nop jmp %g1 + 0xbc ! 0xef5eb0bc
2231 instruction next_insn;
2232 Address next_insn_addr = entry.target_addr() + base_addr + 4;
2233 if( !(readDataSpace((caddr_t)next_insn_addr, sizeof(next_insn),
2234 (char *)&next_insn, true)) ) {
2235 sprintf(errorLine, "read error in process::hasBeenBound addr 0x%lx"
2236 " (readDataSpace next_insn_addr returned 0)\n",
2239 print_read_error_info(entry, target_pdf, base_addr);
2241 // if this is a b,a instruction, then the function has not been bound
2242 if((next_insn.branch.op == FMT2op) && (next_insn.branch.op2 == BICCop2)
2243 && (next_insn.branch.anneal == 1) && (next_insn.branch.cond == BAcond)) {
2247 // if this is a sethi instruction, then it has been bound...get target_addr
2248 instruction third_insn;
2249 Address third_addr = entry.target_addr() + base_addr + 8;
2250 if( !(readDataSpace((caddr_t)third_addr, sizeof(third_insn),
2251 (char *)&third_insn, true)) ) {
2252 sprintf(errorLine, "read error in process::hasBeenBound addr 0x%lx"
2253 " (readDataSpace third_addr returned 0)\n",
2256 print_read_error_info(entry,target_pdf, base_addr);
2259 // get address of bound function, and return the corr. pd_Function
2260 if((next_insn.sethi.op == FMT2op) && (next_insn.sethi.op2 == SETHIop2)
2261 && (third_insn.rest.op == RESTop) && (third_insn.rest.i == 1)
2262 && (third_insn.rest.op3 == JMPLop3)) {
2264 Address new_target = (next_insn.sethi.imm22 << 10) & 0xfffffc00;
2265 new_target |= third_insn.resti.simm13;
2267 target_pdf = findpdFunctionIn(new_target);
2273 // this is a messed up entry
2281 // findCallee: finds the function called by the instruction corresponding
2282 // to the instPoint "instr". If the function call has been bound to an
2283 // address, then the callee function is returned in "target" and the
2284 // instPoint "callee" data member is set to pt to callee's function_base.
2285 // If the function has not yet been bound, then "target" is set to the
2286 // function_base associated with the name of the target function (this is
2287 // obtained by the PLT and relocation entries in the image), and the instPoint
2288 // callee is not set. If the callee function cannot be found, (ex. function
2289 // pointers, or other indirect calls), it returns false.
2290 // Returns false on error (ex. process doesn't contain this instPoint).
2292 // The assumption here is that for all processes sharing the image containing
2293 // this instPoint they are going to bind the call target to the same function.
2294 // For shared objects this is always true, however this may not be true for
2295 // dynamic executables. Two a.outs can be identical except for how they are
2296 // linked, so a call to fuction foo in one version of the a.out may be bound
2297 // to function foo in libfoo.so.1, and in the other version it may be bound to
2298 // function foo in libfoo.so.2. We are currently not handling this case, since
2299 // it is unlikely to happen in practice.
2300 bool process::findCallee(instPoint &instr, function_base *&target){
2302 if((target = const_cast<function_base *>(instr.iPgetCallee()))) {
2303 return true; // callee already set
2306 // find the corresponding image in this process
2307 const image *owner = instr.iPgetOwner();
2308 bool found_image = false;
2309 Address base_addr = 0;
2310 if(symbols == owner) { found_image = true; }
2311 else if(shared_objects){
2312 for(u_int i=0; i < shared_objects->size(); i++){
2313 if(owner == ((*shared_objects)[i])->getImage()) {
2315 base_addr = ((*shared_objects)[i])->getBaseAddress();
2322 return false; // image not found...this is bad
2325 // get the target address of this function
2326 Address target_addr = 0;
2327 // Address insn_addr = instr.iPgetAddress();
2328 target_addr = instr.getTargetAddress();
2331 // this is either not a call instruction or an indirect call instr
2332 // that we can't get the target address
2337 #if defined(sparc_sun_solaris2_4)
2338 // If this instPoint is from a function that was relocated to the heap
2339 // then need to get the target address relative to this image
2340 if(target_addr && instr.relocated_) {
2341 assert(target_addr > base_addr);
2342 target_addr -= base_addr;
2346 // see if there is a function in this image at this target address
2348 pd_Function *pdf = 0;
2349 if( (pdf = owner->findFunctionInInstAndUnInst(target_addr,this)) ) {
2351 instr.set_callee(pdf);
2352 return true; // target found...target is in this image
2355 // else, get the relocation information for this image
2356 const Object &obj = owner->getObject();
2357 const vector<relocationEntry> *fbt;
2358 if(!obj.get_func_binding_table_ptr(fbt)) {
2360 return false; // target cannot be found...it is an indirect call.
2363 // find the target address in the list of relocationEntries
2364 for(u_int i=0; i < fbt->size(); i++) {
2365 if((*fbt)[i].target_addr() == target_addr) {
2366 // check to see if this function has been bound yet...if the
2367 // PLT entry for this function has been modified by the runtime
2369 pd_Function *target_pdf = 0;
2370 if(hasBeenBound((*fbt)[i], target_pdf, base_addr)) {
2371 target = target_pdf;
2372 instr.set_callee(target_pdf);
2373 return true; // target has been bound
2376 // just try to find a function with the same name as entry
2377 target = findOneFunctionFromAll((*fbt)[i].name());
2382 // KLUDGE: this is because we are not keeping more than
2383 // one name for the same function if there is more
2384 // than one. This occurs when there are weak symbols
2385 // that alias global symbols (ex. libm.so.1: "sin"
2386 // and "__sin"). In most cases the alias is the same as
2387 // the global symbol minus one or two leading underscores,
2388 // so here we add one or two leading underscores to search
2389 // for the name to handle the case where this string
2390 // is the name of the weak symbol...this will not fix
2391 // every case, since if the weak symbol and global symbol
2392 // differ by more than leading underscores we won't find
2393 // it...when we parse the image we should keep multiple
2394 // names for pd_Functions
2396 string s = string("_");
2397 s += (*fbt)[i].name();
2398 target = findOneFunctionFromAll(s);
2403 s += (*fbt)[i].name();
2404 target = findOneFunctionFromAll(s);
2418 #if defined(MT_THREAD)
2419 pdThread *process::createThread(
2424 void* resumestate_p,
2429 // creating new thread
2430 thr = new pdThread(this, tid, pos);
2434 if(!threadMap->add(tid,pd_pos)) {
2435 // we run out of space, so we should try to get some more - naim
2436 if (getTable().increaseMaxNumberOfThreads()) {
2437 if (!threadMap->add(tid,pd_pos)) {
2438 // we should be able to add more threads! - naim
2442 // we completely run out of space! - naim
2446 thr->update_pd_pos(pd_pos);
2447 thr->update_resumestate_p(resumestate_p);
2448 function_base *pdf ;
2451 thr->update_stack_addr(stackbase) ;
2452 thr->update_start_pc(startpc) ;
2453 pdf = findFunctionIn(startpc) ;
2454 thr->update_start_func(pdf) ;
2456 pdf = findOneFunction("main");
2458 //thr->update_start_pc(pdf->addr()) ;
2459 thr->update_start_pc(0);
2460 thr->update_start_func(pdf) ;
2462 prstatus_t theStatus;
2463 if (ioctl(proc_fd, PIOCSTATUS, &theStatus) != -1) {
2464 thr->update_stack_addr((stackbase=(unsigned)theStatus.pr_stkbase));
2470 getTable().addThread(thr);
2473 sprintf(errorLine,"+++++ creating new thread{%s}, pd_pos=%u, pos=%u, tid=%d, stack=0x%x, resumestate=0x%x, by[%s]\n",
2474 pdf->prettyName().string_of(), pd_pos,pos,tid,stackbase,resumestate_p, bySelf?"Self":"Parent");
2481 // CALLED for mainThread
2483 void process::updateThread(pdThread *thr, int tid, unsigned pos, void* resumestate_p, resource *rid) {
2486 thr->update_tid(tid, pos);
2488 if(!threadMap->add(tid,pd_pos)) {
2489 // we run out of space, so we should try to get some more - naim
2490 if (getTable().increaseMaxNumberOfThreads()) {
2491 if (!threadMap->add(tid,pd_pos)) {
2492 // we should be able to add more threads! - naim
2496 // we completely run out of space! - naim
2500 thr->update_pd_pos(pd_pos);
2501 thr->update_rid(rid);
2502 thr->update_resumestate_p(resumestate_p);
2503 function_base *f_main = findOneFunction("main");
2506 //unsigned addr = f_main->addr();
2507 //thr->update_start_pc(addr) ;
2508 thr->update_start_pc(0) ;
2509 thr->update_start_func(f_main) ;
2511 prstatus_t theStatus;
2512 if (ioctl(proc_fd, PIOCSTATUS, &theStatus) != -1) {
2513 thr->update_stack_addr((unsigned)theStatus.pr_stkbase);
2518 sprintf(errorLine,"+++++ updateThread--> creating new thread{main}, pd_pos=%u, pos=%u, tid=%d, stack=0x%x, resumestate=0x%x\n",pd_pos,pos,tid,theStatus.pr_stkbase, resumestate_p);
2523 // CALLED from Attach
2525 void process::updateThread(
2531 void* resumestate_p)
2536 sprintf(errorLine," updateThread(tid=%d, pos=%d, stackaddr=0x%x, startpc=0x%x)\n",
2537 tid, pos, stackbase, startpc);
2540 thr->update_tid(tid, pos);
2542 if(!threadMap->add(tid,pd_pos)) {
2543 // we run out of space, so we should try to get some more - naim
2544 if (getTable().increaseMaxNumberOfThreads()) {
2545 if (!threadMap->add(tid,pd_pos)) {
2546 // we should be able to add more threads! - naim
2550 // we completely run out of space! - naim
2555 thr->update_pd_pos(pd_pos);
2556 thr->update_resumestate_p(resumestate_p);
2561 thr->update_start_pc(startpc) ;
2562 pdf = findFunctionIn(startpc) ;
2563 thr->update_start_func(pdf) ;
2564 thr->update_stack_addr(stackbase) ;
2566 pdf = findOneFunction("main");
2568 thr->update_start_pc(startpc) ;
2569 //thr->update_start_pc(pdf->addr()) ;
2570 thr->update_start_func(pdf) ;
2572 prstatus_t theStatus;
2573 if (ioctl(proc_fd, PIOCSTATUS, &theStatus) != -1) {
2574 thr->update_stack_addr((stackbase=(unsigned)theStatus.pr_stkbase));
2580 sprintf(errorLine,"+++++ creating new thread{%s}, pd_pos=%u, pos=%u, tid=%d, stack=0x%xs, resumestate=0x%x\n",
2581 pdf->prettyName().string_of(), pd_pos, pos, tid, stackbase, resumestate_p);
2585 void process::deleteThread(int tid)
2590 for (i=0;i<threads.size();i++) {
2591 if (threads[i]->get_tid() == tid) {
2597 getTable().deleteThread(thr);
2598 unsigned theSize = threads.size();
2599 threads[i] = threads[theSize-1];
2600 threads.resize(theSize-1);
2602 sprintf(errorLine,"----- deleting thread, tid=%d, threads.size()=%d\n",tid,threads.size());