From 95ade9878e40b575f5fbcfac47afada36c722ba0 Mon Sep 17 00:00:00 2001 From: buck Date: Tue, 8 Jul 1997 19:14:00 +0000 Subject: [PATCH] Added support for the x86 Solaris platform and dynamically linked executables to the dyninst API library. --- dyninstAPI/h/BPatch.h | 1 + dyninstAPI/make.module.tmpl | 1 - dyninstAPI/src/BPatch.C | 8 +- dyninstAPI/src/BPatch_point.C | 5 +- dyninstAPI/src/BPatch_thread.C | 30 +- dyninstAPI/src/inst-x86.C | 64 +++- dyninstAPI/src/process.C | 46 ++- dyninstAPI/src/process.h | 6 +- dyninstAPI/src/process2.C | 274 ----------------- dyninstAPI/src/sunos.C | 9 +- dyninstAPI/src/symtab.C | 2 + dyninstAPI/src/unix.C | 11 +- dyninstAPI/src/unix2.C | 518 -------------------------------- dyninstAPI/tests/make.module.tmpl | 8 +- dyninstAPI_RT/make.module.tmpl | 2 - dyninstAPI_RT/src/DYNINSTAPI_RT_EXPORTS | 2 + dyninstAPI_RT/src/RTaix.c | 55 ++++ dyninstAPI_RT/src/RTcommon.c | 28 +- dyninstAPI_RT/src/RTposix.c | 59 ++++ dyninstAPI_RT/src/RTsolaris.c | 134 +++++++++ dyninstAPI_RT/src/RTsunos.c | 56 ++++ 21 files changed, 485 insertions(+), 834 deletions(-) delete mode 100644 dyninstAPI/src/process2.C delete mode 100644 dyninstAPI/src/unix2.C create mode 100644 dyninstAPI_RT/src/RTaix.c create mode 100644 dyninstAPI_RT/src/RTposix.c create mode 100644 dyninstAPI_RT/src/RTsolaris.c create mode 100644 dyninstAPI_RT/src/RTsunos.c diff --git a/dyninstAPI/h/BPatch.h b/dyninstAPI/h/BPatch.h index aaea735..6bee5be 100644 --- a/dyninstAPI/h/BPatch.h +++ b/dyninstAPI/h/BPatch.h @@ -66,6 +66,7 @@ class BPatch { bool typeCheckOn; BPatch_thread *pidToThread(int pid); + public: static BPatch *bpatch; diff --git a/dyninstAPI/make.module.tmpl b/dyninstAPI/make.module.tmpl index 0737958..122a934 100644 --- a/dyninstAPI/make.module.tmpl +++ b/dyninstAPI/make.module.tmpl @@ -28,7 +28,6 @@ SRCS += ../src/BPatch.C \ ../src/ast.C \ ../src/inst.C \ ../src/process.C \ - ../src/process2.C \ ../src/stats.C \ ../src/symtab.C \ ../src/util.C \ diff --git a/dyninstAPI/src/BPatch.C b/dyninstAPI/src/BPatch.C index d916ad4..41c30de 100644 --- a/dyninstAPI/src/BPatch.C +++ b/dyninstAPI/src/BPatch.C @@ -50,7 +50,7 @@ #include "process.h" extern bool dyninstAPI_init(); -extern int dyninstAPI_handleSigChild(int pid, int status); +extern int handleSigChild(int pid, int status); BPatch *BPatch::bpatch = NULL; @@ -112,6 +112,8 @@ BPatch::~BPatch() delete type_Untyped; delete stdTypes; + + bpatch = NULL; } @@ -270,6 +272,8 @@ BPatch_Vector *BPatch::getThreads() */ bool pollForStatusChange() { + assert(BPatch::bpatch != NULL); + bool result = false; int pid, status; @@ -289,7 +293,7 @@ bool pollForStatusChange() else if (WIFEXITED(status)) thread->lastSignal = 0; /* XXX Make into some constant */ } - dyninstAPI_handleSigChild(pid, status); + handleSigChild(pid, status); } return result; } diff --git a/dyninstAPI/src/BPatch_point.C b/dyninstAPI/src/BPatch_point.C index 24cc8dd..f1d62a5 100644 --- a/dyninstAPI/src/BPatch_point.C +++ b/dyninstAPI/src/BPatch_point.C @@ -65,11 +65,14 @@ BPatch_function *BPatch_point::getCalledFunction() #elif defined(rs6000_ibm_aix3_2) || defined(rs6000_ibm_aix4_1) if (point->ipLoc != ipFuncCallPoint) return NULL; +#elif defined(i386_unknown_solaris2_5) || defined(i386_unknown_nt4_0) + if (!point->insnAtPoint().isCall()) + return NULL; #endif function_base *func; if (!proc->findCallee(*point, func)) - return NULL; + return NULL; if (func != NULL) return new BPatch_function(func); diff --git a/dyninstAPI/src/BPatch_thread.C b/dyninstAPI/src/BPatch_thread.C index 1054054..9a8f072 100644 --- a/dyninstAPI/src/BPatch_thread.C +++ b/dyninstAPI/src/BPatch_thread.C @@ -46,11 +46,11 @@ #include "BPatch.h" #include "BPatch_thread.h" -extern process *dyninstAPI_createProcess(const string File, +/* +extern process *createProcess(const string File, vector argv, vector envp, const string dir = ""); -extern process *dyninstAPI_attachProcess(const string &progpath, int pid, - int afterAttach); - +extern process *attachProcess(const string &progpath, int pid, int afterAttach); +*/ /* * BPatch_thread::getPid @@ -95,7 +95,7 @@ BPatch_thread::BPatch_thread(char *path, char *argv[], char *envp[]) envp_vec += envp[i]; } - proc = dyninstAPI_createProcess(path, argv_vec, envp_vec, ""); + proc = createProcess(path, argv_vec, envp_vec, ""); // XXX Should do something more sensible. if (proc == NULL) return; @@ -106,6 +106,9 @@ BPatch_thread::BPatch_thread(char *path, char *argv[], char *envp[]) BPatch::bpatch->registerThread(this); image = new BPatch_image(proc); + + while (!proc->isBootstrappedYet()) + pollForStatusChange(); } @@ -122,16 +125,22 @@ BPatch_thread::BPatch_thread(char *path, int pid) : lastSignal(-1), mutationsActive(true), createdViaAttach(true), detached(false) { - proc = dyninstAPI_attachProcess(path, pid, 1); - - // XXX Should do something more sensible - if (proc == NULL) return; + if (!attachProcess(path, pid, 1, proc)) { + // XXX Should do something more sensible + proc = NULL; + return; + } // Add this object to the list of threads assert(BPatch::bpatch != NULL); BPatch::bpatch->registerThread(this); image = new BPatch_image(proc); + + while (!proc->isBootstrappedYet()) { + pollForStatusChange(); + proc->launchRPCifAppropriate(false, false); + } } @@ -209,7 +218,7 @@ bool BPatch_thread::isStopped() { pollForStatusChange(); - return proc->status() == neonatal || proc->status() == stopped; + return proc->status() == stopped; } @@ -235,7 +244,6 @@ int BPatch_thread::stopSignal() bool BPatch_thread::isTerminated() { if (proc == NULL) return true; - pollForStatusChange(); return proc->status() == exited; diff --git a/dyninstAPI/src/inst-x86.C b/dyninstAPI/src/inst-x86.C index 9a632ef..0a2b12e 100644 --- a/dyninstAPI/src/inst-x86.C +++ b/dyninstAPI/src/inst-x86.C @@ -43,6 +43,10 @@ * inst-x86.C - x86 dependent functions and code generator * * $Log: inst-x86.C,v $ + * Revision 1.24 1997/07/08 19:15:13 buck + * Added support for the x86 Solaris platform and dynamically linked + * executables to the dyninst API library. + * * Revision 1.23 1997/06/23 17:09:29 tamches * include of instPoint.h is new * @@ -183,6 +187,8 @@ extern bool isPowerOf2(int value, int &result); // Size of a jump rel32 instruction #define JUMP_REL32_SZ (5) #define JUMP_SZ (5) +// Size of a call rel32 instruction +#define CALL_REL32_SZ (5) #define PUSH_RM_OPC1 (0xFF) #define PUSH_RM_OPC2 (6) @@ -874,6 +880,7 @@ void emitAddMemImm32(Address dest, int imm, unsigned char *&insn); void emitOpRegImm(int opcode, reg dest, int imm, unsigned char *&insn); void emitMovRegToRM(reg base, int disp, reg src, unsigned char *&insn); void emitMovRMToReg(reg dest, reg base, int disp, unsigned char *&insn); +void emitCallRel32(unsigned disp32, unsigned char *&insn); void generateMTpreamble(char *insn, unsigned &base, process *proc) { @@ -1625,6 +1632,12 @@ void emitJump(unsigned disp32, unsigned char *&insn) { insn += sizeof(int); } +// emit CALL rel32 +void emitCallRel32(unsigned disp32, unsigned char *&insn) { + *insn++ = 0xE8; + *((int *)insn) = disp32; + insn += sizeof(int); +} // set dest=1 if src1 op src2, otherwise dest = 0 void emitRelOp(unsigned op, reg dest, reg src1, reg src2, unsigned char *&insn) { @@ -1811,6 +1824,10 @@ unsigned emit(opCode op, reg src1, reg src2, reg dest, char *ibuf, unsigned &bas base += insn-first; return base; + } else if (op == branchOp) { + emitJump(dest - JUMP_REL32_SZ, insn); + base += JUMP_REL32_SZ; + return(base - JUMP_REL32_SZ); } else if (op == trampPreamble) { // no code is needed here @@ -2047,6 +2064,8 @@ int getInsnCost(opCode op) return(3); } else if (op == ifOp) { return(1+2+1); + } else if (op == branchOp) { + return(1); /* XXX Need to find out what value this should be. */ } else if (op == callOp) { // cost of call only return(1+2+1+1); @@ -2152,7 +2171,7 @@ bool process::heapIsOk(const vector &find_us) { ghb = UINFERIOR_HEAP_BASE; if (!getSymbolInfo(ghb, sym, baseAddr)) { string msg; - msg = string("Cannot find ") + str + string(". Cannot use this application"); + msg = string("Cannot find ") + ghb + string(". Cannot use this application"); statusLine(msg.string_of()); showErrorCallback(50, msg); return false; @@ -2164,7 +2183,7 @@ bool process::heapIsOk(const vector &find_us) { string tt = "DYNINSTtrampTable"; if (!getSymbolInfo(tt, sym, baseAddr)) { string msg; - msg = string("Cannot find ") + str + string(". Cannot use this application"); + msg = string("Cannot find ") + tt + string(". Cannot use this application"); statusLine(msg.string_of()); showErrorCallback(50, msg); return false; @@ -2372,3 +2391,44 @@ bool process::emitInferiorRPCtrailer(void *void_insnPtr, unsigned &base, return true; } + +// process::replaceFunctionCall +// +// Replace the function call at the given instrumentation point with a call to +// a different function, or with a NOOP. In order to replace the call with a +// NOOP, pass NULL as the parameter "func." +// Returns true if sucessful, false if not. Fails if the site is not a call +// site, or if the site has already been instrumented using a base tramp. +// +// Note that right now we can only replace a call instruction that is five +// bytes long (like a call to a 32-bit relative address). +bool process::replaceFunctionCall(const instPoint *point, + const function_base *func) { + // Must be a call site + if (!point->insnAtPoint().isCall()) + return false; + + // Cannot already be instrumented with a base tramp + if (baseMap.defines(point)) + return false; + + // Replace the call + if (func == NULL) { // Replace with NOOPs + unsigned char *newInsn = new unsigned char[point->insnAtPoint().size()]; + unsigned char *p = newInsn; + for (int i = 0; i < point->insnAtPoint().size(); i++) + emitSimpleInsn(NOP, p); + writeTextSpace((void *)point->iPgetAddress(), + point->insnAtPoint().size(), newInsn); + } else { // Replace with a call to a different function + // XXX Right only, call has to be 5 bytes -- sometime, we should make + // it work for other calls as well. + assert(point->insnAtPoint().size() == CALL_REL32_SZ); + unsigned char *newInsn = new unsigned char[CALL_REL32_SZ]; + unsigned char *p = newInsn; + emitCallRel32(func->addr() - (point->iPgetAddress()+CALL_REL32_SZ), p); + writeTextSpace((void *)point->iPgetAddress(), CALL_REL32_SZ, newInsn); + } + + return true; +} diff --git a/dyninstAPI/src/process.C b/dyninstAPI/src/process.C index 2bce0a6..7a47752 100644 --- a/dyninstAPI/src/process.C +++ b/dyninstAPI/src/process.C @@ -1206,7 +1206,6 @@ void process::registerInferiorAttachedSegs(void *inferiorAttachedAtPtr) { #endif -#ifndef BPATCH_LIBRARY extern bool forkNewProcess(string file, string dir, vector argv, vectorenvp, string inputFile, string outputFile, int &traceLink, int &ioLink, @@ -1225,6 +1224,10 @@ process *createProcess(const string File, vector argv, vector en if (!file.prefixed_by("/") && dir.length() > 0) file = dir + "/" + file; +#ifdef BPATCH_LIBRARY + string inputFile; + string outputFile; +#else // check for I/O redirection in arg list. string inputFile; for (unsigned i1=0; i1 argv, vector en argv.resize(argv.size()-2); } } +#endif /* BPATCH_LIBRARY */ int traceLink; int ioLink; @@ -1259,7 +1263,6 @@ process *createProcess(const string File, vector argv, vector en return NULL; } - #if defined(rs6000_ibm_aix3_2) || defined(rs6000_ibm_aix4_1) extern bool establishBaseAddrs(int pid, int &status, bool waitForTrap); int status; @@ -1269,11 +1272,13 @@ process *createProcess(const string File, vector argv, vector en } #endif +#ifndef BPATCH_LIBRARY // NEW: We bump up batch mode here; the matching bump-down occurs after shared objects // are processed (after receiving the SIGSTOP indicating the end of running // DYNINSTinit; more specifically, procStopFromDYNINSTinit(). // Prevents a diabolical w/w deadlock on solaris --ari tp->resourceBatchMode(true); +#endif /* BPATCH_LIBRARY */ image *img = image::parseImage(file); if (!img) { @@ -1318,9 +1323,10 @@ tp->resourceBatchMode(true); processVec += ret; activeProcesses++; +#ifndef BPATCH_LIBRARY if (!costMetric::addProcessToAll(ret)) assert(false); - +#endif // find the signal handler function ret->findSignalHandler(); // should this be in the ctor? @@ -1364,8 +1370,6 @@ tp->resourceBatchMode(true); } - - void process::DYNINSTinitCompletionCallback(process *theProc, void *, // user data unsigned // return value from DYNINSTinit @@ -1374,7 +1378,12 @@ void process::DYNINSTinitCompletionCallback(process *theProc, theProc->handleCompletionOfDYNINSTinit(true); } -bool attachProcess(const string &progpath, int pid, int afterAttach) { + +bool attachProcess(const string &progpath, int pid, int afterAttach +#ifdef BPATCH_LIBRARY + , process *&newProcess +#endif + ) { // implementation of dynRPC::attach() (the igen call) // This is meant to be "the other way" to start a process (competes w/ createProcess) @@ -1460,6 +1469,14 @@ bool attachProcess(const string &progpath, int pid, int afterAttach) { string buffer = string("PID=") + string(pid) + ", running DYNINSTinit()..."; statusLine(buffer.string_of()); +#ifdef BPATCH_LIBRARY + newProcess = theProc; + + vector the_args(2); + + the_args[0] = new AstNode(AstNode::Constant, (void*)3); + the_args[1] = new AstNode(AstNode::Constant, (void*)getpid()); +#else /* BPATCH_LIBRARY */ attach_cerr << "calling DYNINSTinit with args:" << endl; vector the_args(3); @@ -1490,13 +1507,9 @@ bool attachProcess(const string &progpath, int pid, int afterAttach) { This socket is set up in controllerMainLoop (perfStream.C). */ -#ifdef BPATCH_LIBRARY - // Unused by dyninstAPI library - the_args[2] = new AstNode(AstNode::Constant, (void*)0); -#else the_args[2] = new AstNode(AstNode::Constant, (void*)(-1 * traceConnectInfo)); attach_cerr << (-1* getpid()) << endl; -#endif +#endif /* BPATCH_LIBRARY */ AstNode *the_ast = new AstNode("DYNINSTinit", the_args); for (unsigned j=0;j the_args(2); + + the_args[0] = new AstNode(AstNode::Constant, (void*)1); + the_args[1] = new AstNode(AstNode::Constant, (void*)getpid()); + + AstNode *ast = new AstNode("DYNINSTinit", the_args); +#else vector the_args(3); // 2 dummy args when not shm sampling (just don't use -1, which is reserved @@ -3257,6 +3276,7 @@ void process::installBootstrapInst() { for (unsigned j=0; j argv, vector envp, const string dir); -bool attachProcess(const string &progpath, int pid, int afterAttach); +bool attachProcess(const string &progpath, int pid, int afterAttach +#ifdef BPATCH_LIBRARY + , process *&newProcess +#endif + ); void handleProcessExit(process *p, int exitStatus); diff --git a/dyninstAPI/src/process2.C b/dyninstAPI/src/process2.C deleted file mode 100644 index 464c821..0000000 --- a/dyninstAPI/src/process2.C +++ /dev/null @@ -1,274 +0,0 @@ -/* - * Copyright (c) 1996 Barton P. Miller - * - * We provide the Paradyn Parallel Performance Tools (below - * described as Paradyn") on an AS IS basis, and do not warrant its - * validity or performance. We reserve the right to update, modify, - * or discontinue this software at any time. We shall have no - * obligation to supply such updates or modifications or any other - * form of support to you. - * - * This license is for research uses. For such uses, there is no - * charge. We define "research use" to mean you may freely use it - * inside your organization for whatever purposes you see fit. But you - * may not re-distribute Paradyn or parts of Paradyn, in any form - * source or binary (including derivatives), electronic or otherwise, - * to any other organization or entity without our permission. - * - * (for other uses, please contact us at paradyn@cs.wisc.edu) - * - * All warranties, including without limitation, any warranty of - * merchantability or fitness for a particular purpose, are hereby - * excluded. - * - * By your use of Paradyn, you understand and agree that we (or any - * other person or entity with proprietary rights in Paradyn) are - * under no obligation to provide either maintenance services, - * update services, notices of latent defects, or correction of - * defects for Paradyn. - * - * Even if advised of the possibility of such damages, under no - * circumstances shall we (or any other person or entity with - * proprietary rights in the software licensed hereunder) be liable - * to you or any third party for direct, indirect, or consequential - * damages of any character regardless of type of action, including, - * without limitation, loss of profits, loss of use, loss of good - * will, or computer failure or malfunction. You agree to indemnify - * us (and any other person or entity with proprietary rights in the - * software licensed hereunder) for any and all liability it may - * incur to third parties resulting from your use of Paradyn. - */ -/* - * This file contains special versions of some of the functions in process.C - * that have been modified for the dyninstAPI library. - */ -/* - * $Log: process2.C,v $ - * Revision 1.2 1997/05/07 19:03:20 naim - * Getting rid of old support for threads and turning it off until the new - * version is finished. Additionally, new superTable, baseTable and superVector - * classes for future support of multiple threads. The fastInferiorHeap class has - * also changed - naim - * - * Revision 1.1 1997/03/18 19:44:23 buck - * first commit of dyninst library. Also includes: - * moving templates from paradynd to dyninstAPI - * converting showError into a function (in showerror.C) - * many ifdefs for BPATCH_LIBRARY in dyinstAPI/src. - * - * - */ - -extern "C" { -#ifdef PARADYND_PVM -int pvmputenv (const char *); -int pvmendtask(); -#endif -} - -#include "util/h/headers.h" -#include "dyninstAPI/src/symtab.h" -#include "dyninstAPI/src/pdThread.h" -#include "dyninstAPI/src/process.h" -#include "dyninstAPI/src/util.h" -#include "dyninstAPI/src/inst.h" -#include "dyninstAPI/src/instP.h" -#include "dyninstAPI/src/dyninstP.h" -#include "dyninstAPI/src/os.h" -#include "paradynd/src/showerror.h" -#include "paradynd/src/perfStream.h" -#include "dyninstAPI/src/dynamiclinking.h" - -#include "util/h/debugOstream.h" - -#ifdef ATTACH_DETACH_DEBUG -extern debug_ostream attach_cerr; -#else -extern debug_ostream attach_cerr; -#endif - -extern unsigned activeProcesses; // number of active processes -extern vector processVec; - -extern bool dyninstAPI_forkNewProcess(string file, string dir, - vector argv, vectorenvp, string inputFile, - string outputFile, int &traceLink, int &ioLink, int &pid, int &tid, - int &procHandle, int &thrHandle); - -/* - * Create a new instance of the named process. Read the symbols and start - * the program - */ -process *dyninstAPI_createProcess(const string File, vector argv, - vector envp, const string dir = "") -{ - // prepend the directory (if any) to the file, unless the filename - // starts with a / - string file = File; - if (!file.prefixed_by("/") && dir.length() > 0) - file = dir + "/" + file; - - int traceLink; - int ioLink; - int pid; - int tid; - int procHandle; - int thrHandle; - - string inputFile; - string outputFile; - - ioLink = traceLink = -1; - if (!dyninstAPI_forkNewProcess(file, dir, argv, envp, inputFile, outputFile, - traceLink, ioLink, pid, tid, procHandle, thrHandle)) { - // forkNewProcess is resposible for displaying error messages - return NULL; - } - - -#if defined(rs6000_ibm_aix3_2) || defined(rs6000_ibm_aix4_1) - extern bool establishBaseAddrs(int pid, int &status, bool waitForTrap); - int status; - - if (!establishBaseAddrs(pid, status, true)) { - return(NULL); - } -#endif - - image *img = image::parseImage(file); - if (!img) { - // For better error reporting, two failure return values would be useful - // One for simple error like because-file-not-because - // Another for serious errors like found-but-parsing-failed (internal error; - // please report to paradyn@cs.wisc.edu) - - string msg = string("Unable to parse image: ") + file; - showErrorCallback(68, msg.string_of()); - // destroy child process - P_kill(pid, 9); - - return(NULL); - } - - /* parent */ - statusLine("initializing process data structures"); - -#ifdef SHM_SAMPLING - vector theShmHeapStats(3); - theShmHeapStats[0].elemNumBytes = sizeof(intCounter); - theShmHeapStats[0].maxNumElems = numIntCounters; - - theShmHeapStats[1].elemNumBytes = sizeof(tTimer); - theShmHeapStats[1].maxNumElems = numWallTimers; - - theShmHeapStats[2].elemNumBytes = sizeof(tTimer); - theShmHeapStats[2].maxNumElems = numProcTimers; -#endif - - process *ret = new process(pid, img, traceLink, ioLink -#ifdef SHM_SAMPLING - , 7000, // shm seg key to try first - theShmHeapStats -#endif - ); - // change this to a ctor that takes in more args - - assert(ret); - - processVec += ret; - activeProcesses++; - - // find the signal handler function - ret->findSignalHandler(); // should this be in the ctor? - - // initializing vector of threads - thread[0] is really the - // same process - ret->threads += new pdThread(ret); - - // we use this flag to solve race condition between inferiorRPC and - // continueProc message from paradyn - naim - ret->deferredContinueProc = false; - - ret->numOfActCounters_is=0; - ret->numOfActProcTimers_is=0; - ret->numOfActWallTimers_is=0; - - return ret; - -} - - -process *dyninstAPI_attachProcess(const string &progpath, int pid, - int afterAttach) -{ - // implementation of dynRPC::attach() (the igen call) - // This is meant to be "the other way" to start a process (competes w/ createProcess) - - // progpath gives the full path name of the executable, which we use ONLY to - // read the symbol table. - - // We try to make progpath optional, since given pid, we should be able to - // calculate it with a clever enough search of the process' PATH, examining - // its argv[0], examining its current directory, etc. /proc gives us this - // information on solaris...not sure about other platforms... - - // possible values for afterAttach: 1 --> pause, 2 --> run, 0 --> leave as is - - attach_cerr << "welcome to attachProcess for pid " << pid << endl; - - // QUESTION: When we attach to a process, do we want to redirect its stdout/stderr - // (like we do when we fork off a new process the 'usual' way)? - // My first guess would be no. -ari - // But although we may ignore the io, we still need the trace stream. - - // When we attach to a process, we don't fork...so this routine is much simpler - // than its "competitor", createProcess() (above). - - // TODO: What about AIX establishBaseAddrs??? Do that now? - - string fullPathToExecutable = process::tryToFindExecutable(progpath, pid); - if (!fullPathToExecutable.length()) - return NULL; - - image *theImage = image::parseImage(fullPathToExecutable); - if (theImage == NULL) { - // two failure return values would be useful here, to differentiate - // file-not-found vs. catastrophic-parse-error. - string msg = string("Unable to parse image: ") + fullPathToExecutable; - showErrorCallback(68, msg.string_of()); - return NULL; // failure - } - -#ifdef SHM_SAMPLING - vector theShmHeapStats(3); - theShmHeapStats[0].elemNumBytes = sizeof(intCounter); - theShmHeapStats[0].maxNumElems = numIntCounters; - - theShmHeapStats[1].elemNumBytes = sizeof(tTimer); - theShmHeapStats[1].maxNumElems = numWallTimers; - - theShmHeapStats[2].elemNumBytes = sizeof(tTimer); - theShmHeapStats[2].maxNumElems = numProcTimers; -#endif - - // NOTE: the actual attach happens in the process "attach" constructor: - process *theProc = new process(pid, theImage, afterAttach -#ifdef SHM_SAMPLING - ,7000, // shm seg key to try first - theShmHeapStats -#endif - ); - assert(theProc); - - // the attach ctor always leaves us stopped...we may get continued once - // DYNINSTinit has finished running... - assert(theProc->status() == stopped); - - processVec += theProc; - activeProcesses++; - - // find the signal handler function - theProc->findSignalHandler(); // shouldn't this be in the ctor? - - return theProc; // successful -} diff --git a/dyninstAPI/src/sunos.C b/dyninstAPI/src/sunos.C index 28a1eae..e42cabb 100644 --- a/dyninstAPI/src/sunos.C +++ b/dyninstAPI/src/sunos.C @@ -41,6 +41,10 @@ /* * $Log: sunos.C,v $ + * Revision 1.30 1997/07/08 19:15:18 buck + * Added support for the x86 Solaris platform and dynamically linked + * executables to the dyninst API library. + * * Revision 1.29 1997/07/01 16:54:56 tamches * dummy set_breakpoint_for_syscall_completion * @@ -771,13 +775,8 @@ bool process::loopUntilStopped() { if (sig == SIGSTOP) { break; // success } else { -#ifdef BPATCH_LIBRARY - extern int dyninstAPI_handleSigChild(int, int); - dyninstAPI_handleSigChild(pid, waitStatus); -#else extern int handleSigChild(int, int); handleSigChild(pid, waitStatus); -#endif } } else { diff --git a/dyninstAPI/src/symtab.C b/dyninstAPI/src/symtab.C index 84ec057..393326c 100644 --- a/dyninstAPI/src/symtab.C +++ b/dyninstAPI/src/symtab.C @@ -650,7 +650,9 @@ void pdmodule::define() { #endif } +#ifndef BPATCH_LIBRARY resource::send_now(); +#endif } static inline bool findStartSymbol(Object &lf, Address &adr) { diff --git a/dyninstAPI/src/unix.C b/dyninstAPI/src/unix.C index 83a61dd..2319d98 100644 --- a/dyninstAPI/src/unix.C +++ b/dyninstAPI/src/unix.C @@ -100,6 +100,7 @@ bool forkNewProcess(string file, string dir, vector argv, int &pid, int & /*tid*/, int & /*procHandle*/, int & /*thrHandle*/) { +#ifndef BPATCH_LIBRARY // Strange, but using socketpair here doesn't seem to work OK on SunOS. // Pipe works fine. // r = P_socketpair(AF_UNIX, SOCK_STREAM, (int) NULL, tracePipe); @@ -126,6 +127,7 @@ bool forkNewProcess(string file, string dir, vector argv, showErrorCallback(68, msg); return false; } +#endif // // WARNING This code assumes that vfork is used, and a failed exec will @@ -153,6 +155,7 @@ bool forkNewProcess(string file, string dir, vector argv, return false; } +#ifndef BPATCH_LIBRARY close(tracePipe[1]); // parent never writes trace records; it only receives them. @@ -165,6 +168,7 @@ bool forkNewProcess(string file, string dir, vector argv, traceLink = tracePipe[0]; ioLink = ioPipe[0]; +#endif return true; } else if (pid == 0) { @@ -175,6 +179,7 @@ bool forkNewProcess(string file, string dir, vector argv, pvmendtask(); #endif +#ifndef BPATCH_LIBRARY // handle stdio. // We only write to ioPipe. Hence we close ioPipe[0], the read end. Then we @@ -248,6 +253,7 @@ bool forkNewProcess(string file, string dir, vector argv, P_close(fd); // not using descriptor fd any more; close it. } } +#endif /* indicate our desire to be traced */ errno = 0; @@ -266,6 +272,7 @@ bool forkNewProcess(string file, string dir, vector argv, pvmputenv(envp[ep].string_of()); } #endif +#ifndef BPATCH_LIBRARY // hand off info about how to start a paradynd to the application. // used to catch rexec calls, and poe events. // @@ -283,6 +290,7 @@ bool forkNewProcess(string file, string dir, vector argv, strcat(paradynInfo, " "); } P_putenv(paradynInfo); +#endif char **args; args = new char*[argv.size()+1]; @@ -524,6 +532,7 @@ int handleSigChild(int pid, int status) inferiorrpc_cerr << "processed RPC response in SIGSTOP" << endl; break; // don't want to execute ->Stopped() which changes status line } +#ifndef BPATCH_LIBRARY else if (curr->handleStopDueToExecEntry()) { // grabs data from DYNINST_bootstrap_info forkexec_cerr << "fork/exec -- handled stop before exec" << endl; @@ -538,10 +547,10 @@ int handleSigChild(int pid, int status) break; // don't want to change status line in conventional way } +#endif /* BPATCH_LIBRARY */ else { forkexec_cerr << "unhandled SIGSTOP for pid " << curr->getPid() << " so just leaving process in paused state." << endl << flush; } - curr->status_ = prevStatus; // so Stopped() below won't be a nop curr->Stopped(); diff --git a/dyninstAPI/src/unix2.C b/dyninstAPI/src/unix2.C deleted file mode 100644 index e9afb4b..0000000 --- a/dyninstAPI/src/unix2.C +++ /dev/null @@ -1,518 +0,0 @@ -/* - * Copyright (c) 1996 Barton P. Miller - * - * We provide the Paradyn Parallel Performance Tools (below - * described as Paradyn") on an AS IS basis, and do not warrant its - * validity or performance. We reserve the right to update, modify, - * or discontinue this software at any time. We shall have no - * obligation to supply such updates or modifications or any other - * form of support to you. - * - * This license is for research uses. For such uses, there is no - * charge. We define "research use" to mean you may freely use it - * inside your organization for whatever purposes you see fit. But you - * may not re-distribute Paradyn or parts of Paradyn, in any form - * source or binary (including derivatives), electronic or otherwise, - * to any other organization or entity without our permission. - * - * (for other uses, please contact us at paradyn@cs.wisc.edu) - * - * All warranties, including without limitation, any warranty of - * merchantability or fitness for a particular purpose, are hereby - * excluded. - * - * By your use of Paradyn, you understand and agree that we (or any - * other person or entity with proprietary rights in Paradyn) are - * under no obligation to provide either maintenance services, - * update services, notices of latent defects, or correction of - * defects for Paradyn. - * - * Even if advised of the possibility of such damages, under no - * circumstances shall we (or any other person or entity with - * proprietary rights in the software licensed hereunder) be liable - * to you or any third party for direct, indirect, or consequential - * damages of any character regardless of type of action, including, - * without limitation, loss of profits, loss of use, loss of good - * will, or computer failure or malfunction. You agree to indemnify - * us (and any other person or entity with proprietary rights in the - * software licensed hereunder) for any and all liability it may - * incur to third parties resulting from your use of Paradyn. - */ -/* - * This file containts special versions of some of the fuctions in unix.C, - * which have been modified for the dyninstAPI library. - */ -/* - * $Log: unix2.C,v $ - * Revision 1.2 1997/05/02 01:43:33 buck - * Updated dyninstAPI library-only files to work with recent changes to code - * code included in Paradyn. - * - * Revision 1.1.1.1 1997/04/01 20:25:11 buck - * Update Maryland repository with latest from Wisconsin. - * - * Revision 1.1 1997/03/18 19:44:31 buck - * first commit of dyninst library. Also includes: - * moving templates from paradynd to dyninstAPI - * converting showError into a function (in showerror.C) - * many ifdefs for BPATCH_LIBRARY in dyinstAPI/src. - * - * - */ - -#include "util/h/headers.h" -#include "util/h/String.h" -#include "util/h/Vector.h" -#include "paradynd/src/showerror.h" -#include "dyninstAPI/src/os.h" -#include "dyninstAPI/src/util.h" - -// the following are needed for handleSigChild -#include "dyninstAPI/src/process.h" -#include "dyninstAPI/src/instP.h" -#include "dyninstAPI/src/stats.h" -extern process *findProcess(int); - -// The following were all defined in process.C (for no particular reason) -extern debug_ostream attach_cerr; -extern debug_ostream inferiorrpc_cerr; -extern debug_ostream shmsample_cerr; -extern debug_ostream forkexec_cerr; -extern debug_ostream metric_cerr; -extern debug_ostream signal_cerr; -extern debug_ostream sharedobj_cerr; - - -extern "C" { -#ifdef PARADYND_PVM -int pvmputenv (const char *); -int pvmendtask(); -#endif -} - -/***************************************************************************** - * dyninstAPI_forkNewProcess: starts a new process - * Returns true if succesfull. - * - * Arguments: - * file: file to execute - * dir: working directory for the new process - * argv: arguments to new process - * envp: environment **** not in use - * inputFile: where to redirect standard input **** unused - * outputFile: where to redirect standard output **** unused - * traceLink: handle or file descriptor of trace link (read only) **** unused - * ioLink: handle or file descriptor of io link (read only) **** unused - * pid: process id of new process - * tid: thread id for main thread (needed by WindowsNT) - * procHandle: handle for new process (needed by WindowsNT) - * thrHandle: handle for main thread (needed by WindowsNT) - ****************************************************************************/ -bool dyninstAPI_forkNewProcess(string file, string dir, vector argv, - vectorenvp, string inputFile, string outputFile, - int &traceLink, int &ioLink, - int &pid, int & /*tid*/, - int & /*procHandle*/, int & /*thrHandle*/) { - - // - // WARNING This code assumes that vfork is used, and a failed exec will - // corectly change failed in the parent process. - // - - errno = 0; -#ifdef PARADYND_PVM -// must use fork, since pvmendtask will do some writing in the address space - pid = fork(); - // fprintf(stderr, "FORK: pid=%d\n", pid); -#else - pid = vfork(); -#endif - - if (pid > 0) { - - //*** parent - - if (errno) { - sprintf(errorLine, "Unable to start %s: %s\n", file.string_of(), - sys_errlist[errno]); - logLine(errorLine); - showErrorCallback(68, (const char *) errorLine); - return false; - } - - return true; - - } else if (pid == 0) { - //*** child - -#ifdef PARADYND_PVM - if (pvm_running) - pvmendtask(); -#endif - - if ((dir.length() > 0) && (P_chdir(dir.string_of()) < 0)) { - sprintf(errorLine, "cannot chdir to '%s': %s\n", dir.string_of(), - sys_errlist[errno]); - logLine(errorLine); - P__exit(-1); - } - - /* indicate our desire to be traced */ - errno = 0; - OS::osTraceMe(); - if (errno != 0) { - sprintf(errorLine, "ptrace error, exiting, errno=%d\n", errno); - logLine(errorLine); - logLine(sys_errlist[errno]); - showErrorCallback(69, string("Internal error: ") + - string((const char *) errorLine)); - P__exit(-1); // double underscores are correct - } -#ifdef PARADYND_PVM - if (pvm_running && envp.size()) - for (int ep=envp.size()-1; ep>=0; ep--) { - pvmputenv(envp[ep].string_of()); - } -#endif - char **args; - args = new char*[argv.size()+1]; - for (unsigned ai=0; aiStopped(); - break; - - case SIGTRAP: { - // Note that there are now several uses for SIGTRAPs in paradynd. - // The original use was to detect when a ptraced process had - // started up. Several have been added. We must be careful - // to make sure that uses of SIGTRAPs do not conflict. - - signal_cerr << "welcome to SIGTRAP for pid " << curr->getPid() << " status=" << curr->getStatusAsString() << endl; - const bool wasRunning = (curr->status() == running); - curr->status_ = stopped; // probably was 'neonatal' - - //If the list is not empty, it means some previous - //instrumentation has yet need to be finished. - if (instWList.size() != 0) { - // cerr << "instWList is full" << endl; - if(curr -> cleanUpInstrumentation(wasRunning)){ - break; // successfully processed the SIGTRAP - } - } - - if (curr->handleTrapIfDueToRPC()) { - inferiorrpc_cerr << "processed RPC response in SIGTRAP" << endl; - break; - } - - if (curr->inExec) { - // the process has executed a succesful exec, and is now - // stopped at the exit of the exec call. - - forkexec_cerr << "SIGTRAP: inExec is true, so doing process::handleExec()!" << endl; - string buffer = string("process ") + string(curr->getPid()) + - " has performed exec() syscall"; - statusLine(buffer.string_of()); - - // call handleExec to clean our internal data structures, reparse - // symbol table. handleExec does not insert instrumentation or do - // any propagation. Why not? Because it wouldn't be safe -- the - // process hasn't yet been bootstrapped (run DYNINST, etc.) Only - // when we get the breakpoint at the end of DYNINSTinit() is it safe - // to insert instrumentation and allocate timers & counters... - curr->handleExec(); - - // set reachedFirstBreak to false here, so we execute - // the code below, and insert the initial instrumentation - // in the new image. (Actually, this is already done by handleExec()) - curr->reachedFirstBreak = false; - - // fall through... - } - - // Now we expect that this TRAP is the initial trap sent when a ptrace'd - // process completes startup via exec (or when an exec syscall was - // executed in an already-running process). - // But we must query 'reachedFirstBreak' because on machines where we - // attach/detach on pause/continue, a TRAP is generated on each pause! - - if (!curr->reachedFirstBreak) { // vrble should be renamed 'reachedFirstTrap' - // cerr << "!reachedFirstBreak" << endl; - string buffer = string("PID=") + string(pid); - buffer += string(", passed trap at start of program"); - statusLine(buffer.string_of()); - - // initializes the inferiorHeap - // If libdyninst is dynamically linked, this can only be - // called after libdyninst is loaded - curr->initDyninstLib(); - -// (void)(curr->findDynamicLinkingInfo()); // SHOULD THIS BE HERE??? - - curr->reachedFirstBreak = true; - - } - else { - signal_cerr << "SIGTRAP not handled for pid " << pid << " so just leaving process in stopped state" << endl << flush; - } - - break; - } - - case SIGSTOP: - case SIGINT: { - signal_cerr << "welcome to SIGSTOP/SIGINT for proc pid " << curr->getPid() << endl; - - const processState prevStatus = curr->status_; - // assert(prevStatus != stopped); (bombs on sunos and AIX, when lots of spurious sigstops are delivered) - - curr->status_ = stopped; - // the following routines expect (and assert) this status. - -#ifdef BPATCH_NOT_YET - int result = curr->procStopFromDYNINSTinit(); - assert(result >=0 && result <= 2); - if (result != 0) { - forkexec_cerr << "processed SIGSTOP from DYNINSTinit for pid " << curr->getPid() << endl << flush; - - if (result == 1) { - assert(curr->status_ == stopped); - // DYNINSTinit() after normal startup, after fork, or after exec - // syscall was made by a running program; leave paused - // (tp->newProgramCallback() to paradyn will result in the process - // being continued soon enough, assuming the applic was running, - // which is true in all cases except when an applic is just being - // started up). Fall through (we want the status line to change) - } else { - assert(result == 2); - break; // don't fall through...prog is finishing the inferiorRPC - } - } - else if (curr->handleTrapIfDueToRPC()) { - inferiorrpc_cerr << "processed RPC response in SIGSTOP" << endl; - break; // don't want to execute ->Stopped() which changes status line - } - else if (curr->handleStopDueToExecEntry()) { - // grabs data from DYNINST_bootstrap_info - forkexec_cerr << "fork/exec -- handled stop before exec" << endl; - string buffer = string("process ") + string(curr->getPid()) + - " performing exec() syscall..."; - statusLine(buffer.string_of()); - - // note: status will now be 'running', since handleStopDueToExec() - // did a continueProc() to let the exec() syscall go forward. - assert(curr->status_ == running); - // would neonatal be better? or exited? - - break; // don't want to change status line in conventional way - } - else { - forkexec_cerr << "unhandled SIGSTOP for pid " << curr->getPid() << " so just leaving process in paused state." << endl << flush; - } -#endif /* BPATCH_NOT_YET */ - - curr->status_ = prevStatus; // so Stopped() below won't be a nop - curr->Stopped(); - - break; - } - - case SIGILL: - signal_cerr << "welcome to SIGILL" << endl << flush; - curr->status_ = stopped; - - if (curr->handleTrapIfDueToRPC()) { - inferiorrpc_cerr << "processed RPC response in SIGILL" << endl; cerr.flush(); - - break; // we don't forward the signal -- on purpose - } - else - // fall through, on purpose - ; - - case SIGIOT: - case SIGBUS: -#if (defined(POWER_DEBUG) || defined(HP_DEBUG)) && (defined(rs6000_ibm_aix4_1) || defined(hppa1_1_hp_hpux)) - // In this way, we will detach from the application and we - // will be able to attach again using gdb. We need to send - // a kill -ILL pid signal to the application in order to - // get here - naim -#if defined(rs6000_ibm_aix4_1) - if (ptrace(PT_DETACH,pid,(int *) 1, SIGSTOP, NULL) == -1) { -#else - if (ptrace(PT_DETACH, pid, 1, SIGSTOP, NULL) == -1) { -#endif - logLine("ptrace error\n"); - } -#else - signal_cerr << "caught signal, dying... (sig=" - << WSTOPSIG(status) << ")" << endl << flush; - - curr->status_ = stopped; - curr->dumpImage(); - curr->continueWithForwardSignal(WSTOPSIG(status)); -#endif - break; - - case SIGALRM: -#ifndef SHM_SAMPLING - // Due to the DYNINSTin_sample variable, it's safest to launch - // inferior-RPCs only when we know that the inferior is not in the - // middle of processing an alarm-expire. Otherwise, code that does - // stuff like call DYNINSTstartWallTimer will appear to do nothing - // (DYNINSTstartWallTimer will be invoked but will see that - // DYNINSTin_sample is set and so bails out!!!) - // Ick. - if (curr->existsRPCreadyToLaunch()) { - curr -> status_ = stopped; - (void)curr->launchRPCifAppropriate(true); - break; // sure, we lose the SIGALARM, but so what. - } - else - ; // no break, on purpose -#endif - - case SIGCHLD: - case SIGUSR1: - case SIGUSR2: - case SIGVTALRM: - case SIGCONT: - case SIGSEGV: // treadmarks needs this signal -#if (defined(POWER_DEBUG) || defined(HP_DEBUG)) && (defined(rs6000_ibm_aix4_1) || defined(hppa1_1_hp_hpux)) - // In this way, we will detach from the application and we - // will be able to attach again using gdb - naim - if (sig==SIGSEGV) - { - logLine("==> Detaching paradynd from the application...\n"); -#if defined(rs6000_ibm_aix4_1) - if (ptrace(PT_DETACH,pid,(int *) 1, SIGSTOP, NULL) == -1) -#else - if (ptrace(PT_DETACH,pid, 1, SIGSTOP, NULL) == -1) -#endif - logLine("ptrace error\n"); - break; - } -#endif - if (!curr->continueWithForwardSignal(WSTOPSIG(status))) { - logLine("error in forwarding signal\n"); - showErrorCallback(38, "Error in forwarding signal"); - //P_abort(); - } - - break; - -#ifdef notdef - // XXXX for debugging - case SIGSEGV: // treadmarks needs this signal - sprintf(errorLine, "DEBUG: forwarding signal (sig=%d, pid=%d)\n" - , WSTOPSIG(status), pid); - logLine(errorLine); -#endif - default: - if (!curr->continueWithForwardSignal(WSTOPSIG(status))) { - logLine("error in forwarding signal\n"); - P_abort(); - } - break; - - } - } else if (WIFEXITED(status)) { -#if defined(PARADYND_PVM) -// if (pvm_running) { -// PDYN_reportSIGCHLD (pid, WEXITSTATUS(status)); -// } -#endif - sprintf(errorLine, "Process %d has terminated\n", curr->getPid()); - statusLine(errorLine); - logLine(errorLine); - - printDyninstStats(); - handleProcessExit(curr, WEXITSTATUS(status)); - } else if (WIFSIGNALED(status)) { - sprintf(errorLine, "process %d has terminated on signal %d\n", curr->getPid(), WTERMSIG(status)); - logLine(errorLine); - statusLine(errorLine); - handleProcessExit(curr, WTERMSIG(status)); - } else { - sprintf(errorLine, "Unknown state %d from process %d\n", status, curr->getPid()); - logLine(errorLine); - showErrorCallback(39,(const char *) errorLine); - } - return(0); -} diff --git a/dyninstAPI/tests/make.module.tmpl b/dyninstAPI/tests/make.module.tmpl index c4977e4..5c8c045 100644 --- a/dyninstAPI/tests/make.module.tmpl +++ b/dyninstAPI/tests/make.module.tmpl @@ -4,6 +4,10 @@ # from within an architecture-specific Makefile. # # $Log: make.module.tmpl,v $ +# Revision 1.4 1997/07/08 19:15:27 buck +# Added support for the x86 Solaris platform and dynamically linked +# executables to the dyninst API library. +# # Revision 1.3 1997/06/23 19:16:07 buck # Added features to the dyninst API library, including an optional "else" # in a BPatch_ifExpr; the BPatch_setMutationsActive call to temporarily @@ -36,8 +40,8 @@ SRCS += ../src/test1.C APP_DIR = '"$(PARADYN_ROOT)/bin/$(PLATFORM)"' -CXXFLAGS += -I../../h -DTEST_APP_DIR=$(APP_DIR) -CFLAGS += -I../../h -DTEST_APP_DIR=$(APP_DIR) +CXXFLAGS += -I../../h +CFLAGS += -I../../h #LDFLAGS += -static $(TO_CORE)/../lib/$(PLATFORM)/libdyninstAPI_RT.o LIBS += -ldyninstAPI -lpdutil diff --git a/dyninstAPI_RT/make.module.tmpl b/dyninstAPI_RT/make.module.tmpl index e9d3ec0..f69e7a3 100644 --- a/dyninstAPI_RT/make.module.tmpl +++ b/dyninstAPI_RT/make.module.tmpl @@ -14,8 +14,6 @@ endif MODCC = $(CC) MODCFLAGS = $(CFLAGS) -#SRCS += ../src/RTend.c - SRCS += ../src/RTcommon.c ifdef USES_SHM_SAMPLING diff --git a/dyninstAPI_RT/src/DYNINSTAPI_RT_EXPORTS b/dyninstAPI_RT/src/DYNINSTAPI_RT_EXPORTS index 31e7a2b..af3be5a 100644 --- a/dyninstAPI_RT/src/DYNINSTAPI_RT_EXPORTS +++ b/dyninstAPI_RT/src/DYNINSTAPI_RT_EXPORTS @@ -4,3 +4,5 @@ DYNINSTobsCostLow DYNINSTdata DYNINSTtext DYNINSTglobalData +DYNINSTinit +DYNINSTos_init diff --git a/dyninstAPI_RT/src/RTaix.c b/dyninstAPI_RT/src/RTaix.c new file mode 100644 index 0000000..e616087 --- /dev/null +++ b/dyninstAPI_RT/src/RTaix.c @@ -0,0 +1,55 @@ +/* + * Copyright (c) 1996 Barton P. Miller + * + * We provide the Paradyn Parallel Performance Tools (below + * described as Paradyn") on an AS IS basis, and do not warrant its + * validity or performance. We reserve the right to update, modify, + * or discontinue this software at any time. We shall have no + * obligation to supply such updates or modifications or any other + * form of support to you. + * + * This license is for research uses. For such uses, there is no + * charge. We define "research use" to mean you may freely use it + * inside your organization for whatever purposes you see fit. But you + * may not re-distribute Paradyn or parts of Paradyn, in any form + * source or binary (including derivatives), electronic or otherwise, + * to any other organization or entity without our permission. + * + * (for other uses, please contact us at paradyn@cs.wisc.edu) + * + * All warranties, including without limitation, any warranty of + * merchantability or fitness for a particular purpose, are hereby + * excluded. + * + * By your use of Paradyn, you understand and agree that we (or any + * other person or entity with proprietary rights in Paradyn) are + * under no obligation to provide either maintenance services, + * update services, notices of latent defects, or correction of + * defects for Paradyn. + * + * Even if advised of the possibility of such damages, under no + * circumstances shall we (or any other person or entity with + * proprietary rights in the software licensed hereunder) be liable + * to you or any third party for direct, indirect, or consequential + * damages of any character regardless of type of action, including, + * without limitation, loss of profits, loss of use, loss of good + * will, or computer failure or malfunction. You agree to indemnify + * us (and any other person or entity with proprietary rights in the + * software licensed hereunder) for any and all liability it may + * incur to third parties resulting from your use of Paradyn. + */ + +/************************************************************************ + * RTaix.c: mutatee-side library function specific to AIX +************************************************************************/ + +/************************************************************************ + * void DYNINSTos_init(void) + * + * os initialization function +************************************************************************/ + +void +DYNINSTos_init(int calledByFork, int calledByAttach) +{ +} diff --git a/dyninstAPI_RT/src/RTcommon.c b/dyninstAPI_RT/src/RTcommon.c index 6e3f227..6dfd194 100644 --- a/dyninstAPI_RT/src/RTcommon.c +++ b/dyninstAPI_RT/src/RTcommon.c @@ -38,10 +38,36 @@ * software licensed hereunder) for any and all liability it may * incur to third parties resulting from your use of Paradyn. */ -#include "rtinst/h/rtinst.h" +#include +#include "dyninstAPI_RT/h/rtinst.h" +#include "dyninstAPI_RT/h/trace.h" + +extern void DYNINSTbreakPoint(); +extern void DYNINSTos_init(int calledByFork, int calledByAttach); unsigned int DYNINSTversion = 1; unsigned int DYNINSTobsCostLow; +struct DYNINST_bootstrapStruct DYNINST_bootstrap_info; + char DYNINSTdata[SYN_INST_BUF_SIZE]; char DYNINSTglobalData[SYN_INST_BUF_SIZE]; + +/* + * The Dyninst API arranges for this function to be called at the entry to + * main(). + */ +void DYNINSTinit(int cause, int pid) +{ + int calledByFork = 0, calledByAttach = 0; + + if (cause == 2) calledByFork = 1; + else if (cause == 3) calledByAttach = 1; + + DYNINSTos_init(calledByFork, calledByAttach); + + DYNINST_bootstrap_info.pid = getpid(); + DYNINST_bootstrap_info.event = cause; + + DYNINSTbreakPoint(); +} diff --git a/dyninstAPI_RT/src/RTposix.c b/dyninstAPI_RT/src/RTposix.c new file mode 100644 index 0000000..5a6d96f --- /dev/null +++ b/dyninstAPI_RT/src/RTposix.c @@ -0,0 +1,59 @@ +/* + * Copyright (c) 1996 Barton P. Miller + * + * We provide the Paradyn Parallel Performance Tools (below + * described as Paradyn") on an AS IS basis, and do not warrant its + * validity or performance. We reserve the right to update, modify, + * or discontinue this software at any time. We shall have no + * obligation to supply such updates or modifications or any other + * form of support to you. + * + * This license is for research uses. For such uses, there is no + * charge. We define "research use" to mean you may freely use it + * inside your organization for whatever purposes you see fit. But you + * may not re-distribute Paradyn or parts of Paradyn, in any form + * source or binary (including derivatives), electronic or otherwise, + * to any other organization or entity without our permission. + * + * (for other uses, please contact us at paradyn@cs.wisc.edu) + * + * All warranties, including without limitation, any warranty of + * merchantability or fitness for a particular purpose, are hereby + * excluded. + * + * By your use of Paradyn, you understand and agree that we (or any + * other person or entity with proprietary rights in Paradyn) are + * under no obligation to provide either maintenance services, + * update services, notices of latent defects, or correction of + * defects for Paradyn. + * + * Even if advised of the possibility of such damages, under no + * circumstances shall we (or any other person or entity with + * proprietary rights in the software licensed hereunder) be liable + * to you or any third party for direct, indirect, or consequential + * damages of any character regardless of type of action, including, + * without limitation, loss of profits, loss of use, loss of good + * will, or computer failure or malfunction. You agree to indemnify + * us (and any other person or entity with proprietary rights in the + * software licensed hereunder) for any and all liability it may + * incur to third parties resulting from your use of Paradyn. + */ + +/************************************************************************ + * RTposix.c: runtime instrumentation functions for generic posix. + ************************************************************************/ + +#include +#include +#include + +/************************************************************************ + * void DYNINSTbreakPoint(void) + * + * stop oneself. +************************************************************************/ + +void DYNINSTbreakPoint(void) +{ + kill(getpid(), SIGSTOP); +} diff --git a/dyninstAPI_RT/src/RTsolaris.c b/dyninstAPI_RT/src/RTsolaris.c new file mode 100644 index 0000000..3e866b2 --- /dev/null +++ b/dyninstAPI_RT/src/RTsolaris.c @@ -0,0 +1,134 @@ +/* + * Copyright (c) 1996 Barton P. Miller + * + * We provide the Paradyn Parallel Performance Tools (below + * described as Paradyn") on an AS IS basis, and do not warrant its + * validity or performance. We reserve the right to update, modify, + * or discontinue this software at any time. We shall have no + * obligation to supply such updates or modifications or any other + * form of support to you. + * + * This license is for research uses. For such uses, there is no + * charge. We define "research use" to mean you may freely use it + * inside your organization for whatever purposes you see fit. But you + * may not re-distribute Paradyn or parts of Paradyn, in any form + * source or binary (including derivatives), electronic or otherwise, + * to any other organization or entity without our permission. + * + * (for other uses, please contact us at paradyn@cs.wisc.edu) + * + * All warranties, including without limitation, any warranty of + * merchantability or fitness for a particular purpose, are hereby + * excluded. + * + * By your use of Paradyn, you understand and agree that we (or any + * other person or entity with proprietary rights in Paradyn) are + * under no obligation to provide either maintenance services, + * update services, notices of latent defects, or correction of + * defects for Paradyn. + * + * Even if advised of the possibility of such damages, under no + * circumstances shall we (or any other person or entity with + * proprietary rights in the software licensed hereunder) be liable + * to you or any third party for direct, indirect, or consequential + * damages of any character regardless of type of action, including, + * without limitation, loss of profits, loss of use, loss of good + * will, or computer failure or malfunction. You agree to indemnify + * us (and any other person or entity with proprietary rights in the + * software licensed hereunder) for any and all liability it may + * incur to third parties resulting from your use of Paradyn. + */ + +/************************************************************************ + * RTsolaris.c: mutatee-side library function specific to Solaris +************************************************************************/ + +#include +#include +#include +#include + +#include "dyninstAPI_RT/h/rtinst.h" + +/************************************************************************ + * void DYNINSTos_init(void) + * + * os initialization function +************************************************************************/ + +void +DYNINSTos_init(int calledByFork, int calledByAttach) +{ + /* + Install trap handler. + This is currently being used only on the x86 platform. + */ +#ifdef i386_unknown_solaris2_5 + void DYNINSTtrapHandler(int sig, siginfo_t *info, ucontext_t *uap); + struct sigaction act; + act.sa_handler = DYNINSTtrapHandler; + act.sa_flags = 0; + sigfillset(&act.sa_mask); + if (sigaction(SIGTRAP, &act, 0) != 0) { + perror("sigaction(SIGTRAP)"); + assert(0); + abort(); + } +#endif + + +} + + + + + +/**************************************************************************** + The trap handler. Currently being used only on x86 platform. + + Traps are used when we can't insert a jump at a point. The trap + handler looks up the address of the base tramp for the point that + uses the trap, and set the pc to this base tramp. + The paradynd is responsible for updating the tramp table when it + inserts instrumentation. +*****************************************************************************/ + +#ifdef i386_unknown_solaris2_5 +trampTableEntry DYNINSTtrampTable[TRAMPTABLESZ]; +unsigned DYNINSTtotalTraps = 0; + +static unsigned lookup(unsigned key) { + unsigned u; + unsigned k; + for (u = HASH1(key); 1; u = (u + HASH2(key)) % TRAMPTABLESZ) { + k = DYNINSTtrampTable[u].key; + if (k == 0) + return 0; + else if (k == key) + return DYNINSTtrampTable[u].val; + } + /* not reached */ + assert(0); + abort(); +} + +void DYNINSTtrapHandler(int sig, siginfo_t *info, ucontext_t *uap) { + unsigned pc = uap->uc_mcontext.gregs[PC]; + unsigned nextpc = lookup(pc); + + if (!nextpc) { + /* kludge: maybe the PC was not automatically adjusted after the trap */ + /* this happens for a forked process */ + pc--; + nextpc = lookup(pc); + } + + if (nextpc) { + uap->uc_mcontext.gregs[PC] = nextpc; + } else { + assert(0); + abort(); + } + DYNINSTtotalTraps++; +} +#endif diff --git a/dyninstAPI_RT/src/RTsunos.c b/dyninstAPI_RT/src/RTsunos.c new file mode 100644 index 0000000..a5e9153 --- /dev/null +++ b/dyninstAPI_RT/src/RTsunos.c @@ -0,0 +1,56 @@ +/* + * Copyright (c) 1996 Barton P. Miller + * + * We provide the Paradyn Parallel Performance Tools (below + * described as Paradyn") on an AS IS basis, and do not warrant its + * validity or performance. We reserve the right to update, modify, + * or discontinue this software at any time. We shall have no + * obligation to supply such updates or modifications or any other + * form of support to you. + * + * This license is for research uses. For such uses, there is no + * charge. We define "research use" to mean you may freely use it + * inside your organization for whatever purposes you see fit. But you + * may not re-distribute Paradyn or parts of Paradyn, in any form + * source or binary (including derivatives), electronic or otherwise, + * to any other organization or entity without our permission. + * + * (for other uses, please contact us at paradyn@cs.wisc.edu) + * + * All warranties, including without limitation, any warranty of + * merchantability or fitness for a particular purpose, are hereby + * excluded. + * + * By your use of Paradyn, you understand and agree that we (or any + * other person or entity with proprietary rights in Paradyn) are + * under no obligation to provide either maintenance services, + * update services, notices of latent defects, or correction of + * defects for Paradyn. + * + * Even if advised of the possibility of such damages, under no + * circumstances shall we (or any other person or entity with + * proprietary rights in the software licensed hereunder) be liable + * to you or any third party for direct, indirect, or consequential + * damages of any character regardless of type of action, including, + * without limitation, loss of profits, loss of use, loss of good + * will, or computer failure or malfunction. You agree to indemnify + * us (and any other person or entity with proprietary rights in the + * software licensed hereunder) for any and all liability it may + * incur to third parties resulting from your use of Paradyn. + */ + +/************************************************************************ + * RTsunos.c: mutatee-side library function specific to SunOS +************************************************************************/ + + +/************************************************************************ + * void DYNINSTos_init(void) + * + * os initialization function +************************************************************************/ + +void +DYNINSTos_init(int calledByFork, int calledByAttach) +{ +} -- 1.8.3.1