2 * See the dyninst/COPYRIGHT file for copyright information.
4 * We provide the Paradyn Tools (below described as "Paradyn")
5 * on an AS IS basis, and do not warrant its validity or performance.
6 * We reserve the right to update, modify, or discontinue this
7 * software at any time. We shall have no obligation to supply such
8 * updates or modifications or any other form of support to you.
10 * By your use of Paradyn, you understand and agree that we (or any
11 * other person or entity with proprietary rights in Paradyn) are
12 * under no obligation to provide either maintenance services,
13 * update services, notices of latent defects, or correction of
14 * defects for Paradyn.
16 * This library is free software; you can redistribute it and/or
17 * modify it under the terms of the GNU Lesser General Public
18 * License as published by the Free Software Foundation; either
19 * version 2.1 of the License, or (at your option) any later version.
21 * This library is distributed in the hope that it will be useful,
22 * but WITHOUT ANY WARRANTY; without even the implied warranty of
23 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
24 * Lesser General Public License for more details.
26 * You should have received a copy of the GNU Lesser General Public
27 * License along with this library; if not, write to the Free Software
28 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
35 #include "BPatch_dll.h"
36 #include "BPatch_Vector.h"
37 #include "BPatch_Set.h"
38 #include "BPatch_thread.h"
39 #include "BPatch_type.h"
40 #include "BPatch_process.h"
41 #include "BPatch_enums.h"
42 #include "BPatch_callbacks.h"
45 #include "dyninstversion.h"
47 class BPatch_typeCollection;
55 //Keep old versions defined, that way someone can test if we're more
56 // at or more recent than version 5.1 with '#if defined(DYNINST_5_1)'
57 //If they want to get the current version, they should use DYNINST_MAJOR,
58 // DYNINST_MINOR, and DYNINST_SUBMINOR
72 #define DYNINST_MAJOR DYNINST_MAJOR_VERSION
73 #define DYNINST_MINOR DYNINST_MINOR_VERSION
74 #define DYNINST_SUBMINOR DYNINST_PATCH_VERSION
78 #pragma warning(disable:4251)
81 // BPatch_stats is a collection of instrumentation statistics.
82 // Introduced to export this information to paradyn, which
83 // produces a summary of these numbers upon application exit.
84 // It probably makes more sense to maintain such numbers on a
85 // per-process basis. But is set up globally due to historical
89 unsigned int pointsUsed;
90 unsigned int totalMiniTramps;
91 unsigned int trampBytes;
92 unsigned int ptraceOtherOps;
93 unsigned int ptraceOps;
94 unsigned int ptraceBytes;
95 unsigned int insnGenerated;
98 // --------------------------------------------------------------------
99 // This is a purposefully undocumented prototype of a "remote debugging"
100 // interface. Meant to generalize debuggers like remote gdb and wtx.
103 BPATCH_REMOTE_DEBUG_WTX,
105 BPATCH_REMOTE_DEBUG_END
112 } BPatch_remoteWtxInfo;
115 BPatch_remote_t type;
118 // --------------------------------------------------------------------
120 class BPATCH_DLL_EXPORT BPatch {
121 friend class BPatch_thread;
122 friend class BPatch_process;
123 friend class BPatch_point;
124 friend class PCProcess;
125 friend class func_instance;
127 BPatch_libInfo *info;
132 bool baseTrampDeletionOn;
134 /* If true, trampolines can recurse to their heart's content.
136 bool trampRecursiveOn;
138 bool forceRelocation_NP;
139 /* If true,allows automatic relocation of functions if dyninst
140 deems it necessary. Defaults to true */
141 bool autoRelocation_NP;
143 /* If true, we save FPRs in situations we normally would
145 bool saveFloatingPointsOn;
146 bool forceSaveFloatingPointsOn;
148 /* If true, we will use liveness calculations to avoid saving
149 registers on platforms that support it.
151 bool livenessAnalysisOn_;
152 /* How far through the CFG do we follow calls? */
153 int livenessAnalysisDepth_;
155 /* If true, override requests to block while waiting for events,
159 /* If true, deep parsing (anything beyond symtab info) is delayed until
161 /* Note: several bpatch constructs have "access everything" behavior,
162 which will trigger full parsing. This should be looked into. */
163 bool delayedParsing_;
170 /* this is used to denote the fully qualified name of the prelink command on linux */
171 char *systemPrelinkCommand;
173 // Wrapper - start process running if it was not deleted.
174 // We use this at the end of callbacks to user code, since those
175 // callbacks may delete BPatch objects.
176 void continueIfExists(int pid);
178 /* Internal notification file descriptor - a pipe */
179 int notificationFDOutput_;
180 int notificationFDInput_;
181 // Easier than non-blocking reads... there is either 1 byte in the pipe or 0.
182 bool FDneedsPolling_;
185 BPatchErrorCallback errorCallback;
186 BPatchForkCallback preForkCallback;
187 BPatchForkCallback postForkCallback;
188 BPatchExecCallback execCallback;
189 BPatchExitCallback exitCallback;
190 BPatchOneTimeCodeCallback oneTimeCodeCallback;
191 BPatchDynLibraryCallback dynLibraryCallback;
192 BPatchAsyncThreadEventCallback threadCreateCallback;
193 BPatchAsyncThreadEventCallback threadDestroyCallback;
194 BPatchDynamicCallSiteCallback dynamicCallSiteCallback;
195 InternalSignalHandlerCallback signalHandlerCallback;
196 std::set<long> callbackSignals;
197 InternalCodeOverwriteCallback codeOverwriteCallback;
199 BPatch_Vector<BPatchUserEventCallback> userEventCallbacks;
200 BPatch_Vector<BPatchStopThreadCallback> stopThreadCallbacks;
202 // If we're destroying everything, skip cleaning up some intermediate
210 static BPatch *bpatch;
212 static BPatch *getBPatch();
213 BPatch_builtInTypeCollection *builtInTypes;
214 BPatch_typeCollection *stdTypes;
215 BPatch_typeCollection *APITypes; //API/User defined types
216 BPatch_type *type_Error;
217 BPatch_type *type_Untyped;
219 // The following are only to be called by the library:
220 // These functions are not locked.
221 void registerProvisionalThread(int pid);
222 void registerForkedProcess(PCProcess *parentProc, PCProcess *childProc);
223 void registerForkingProcess(int forkingPid, PCProcess *proc);
225 void registerExecExit(PCProcess *proc);
226 void registerExecCleanup(PCProcess *proc, char *arg0);
228 void registerNormalExit(PCProcess *proc, int exitcode);
229 void registerSignalExit(PCProcess *proc, int signalnum);
231 void registerThreadExit(PCProcess *llproc, PCThread *llthread);
232 bool registerThreadCreate(BPatch_process *proc, BPatch_thread *newthr);
234 void registerProcess(BPatch_process *process, int pid=0);
235 void unRegisterProcess(int pid, BPatch_process *proc);
237 void registerUserEvent(BPatch_process *process, void *buffer,
238 unsigned int bufsize);
240 void registerDynamicCallsiteEvent(BPatch_process *process, Dyninst::Address callTarget,
241 Dyninst::Address callAddr);
243 void registerStopThreadCallback(BPatchStopThreadCallback stopCB);
244 int getStopThreadCallbackID(BPatchStopThreadCallback stopCB);
246 void registerLoadedModule(PCProcess *process, mapped_object *obj);
247 void registerUnloadedModule(PCProcess *process, mapped_object *obj);
249 BPatch_thread *getThreadByPid(int pid, bool *exists = NULL);
250 BPatch_process *getProcessByPid(int pid, bool *exists = NULL);
252 static void reportError(BPatchErrorLevel severity, int number, const char *str);
254 void clearError() { lastError = 0; }
255 int getLastError() { return lastError; }
256 // End of functions that are for internal use only
266 static const char *getEnglishErrorString(int number);
267 static void formatErrorString(char *dst, int size,
268 const char *fmt, const char * const *params);
270 // BPatch::isTypeChecked:
271 // returns whether type checking is on.
272 bool isTypeChecked();
274 // BPatch::parseDebugInfo:
275 // returns whether debugging information is set to be parsed
276 bool parseDebugInfo();
278 // BPatch::baseTrampDeletion:
279 // returns whether base trampolines are set to be deleted
280 bool baseTrampDeletion();
282 // BPatch::setPrelinkCommand
283 // sets the fully qualified path name of the prelink command
284 void setPrelinkCommand(char *command);
286 // BPatch::getPrelinkCommand
287 // gets the fully qualified path name of the prelink command
288 char* getPrelinkCommand();
290 // BPatch::isTrampRecursive:
291 // returns whether trampolines are set to handle recursive instrumentation
292 bool isTrampRecursive();
294 // BPatch::isMergeTramp:
295 // returns whether base tramp and mini-tramp is merged
298 // BPatch::saveFPROn:
299 // returns whether base tramp and mini-tramp is merged
302 // BPatch::forceSaveFPROn:
303 // returns whether base tramp and mini-tramp is merged
304 bool isForceSaveFPROn();
307 // BPatch::hasForcedRelocation_NP:
308 // returns whether all instrumented functions will be relocated
311 bool hasForcedRelocation_NP();
313 // BPatch::autoRelocationsOn:
314 // returns whether functions will be relocated when appropriate
317 bool autoRelocationOn();
320 // BPatch::delayedParsingOn:
321 // returns whether inst info is parsed a priori, or on demand
324 bool delayedParsingOn();
328 bool livenessAnalysisOn();
331 int livenessAnalysisDepth();
334 // User-specified callback functions...
336 // BPatch::registerErrorCallback:
337 // Register error handling/reporting callback
340 BPatchErrorCallback registerErrorCallback(BPatchErrorCallback function);
342 // BPatch::registerDynLibraryCallback:
343 // Register callback for new library events (eg. load)
346 BPatchDynLibraryCallback registerDynLibraryCallback(BPatchDynLibraryCallback func);
348 // BPatch::registerPostForkCallback:
349 // Register callback to handle mutatee fork events (before fork)
352 BPatchForkCallback registerPostForkCallback(BPatchForkCallback func);
354 // BPatch::registerPreForkCallback:
355 // Register callback to handle mutatee fork events (before fork)
358 BPatchForkCallback registerPreForkCallback(BPatchForkCallback func);
360 // BPatch::registerExecCallback:
361 // Register callback to handle mutatee exec events
363 BPatchExecCallback registerExecCallback(BPatchExecCallback func);
365 // BPatch::registerExitCallback:
366 // Register callback to handle mutatee exit events
369 BPatchExitCallback registerExitCallback(BPatchExitCallback func);
371 // BPatch::registerOneTimeCodeCallback:
372 // Register callback to run at completion of oneTimeCode
374 BPatchOneTimeCodeCallback registerOneTimeCodeCallback(BPatchOneTimeCodeCallback func);
376 // BPatch::registerThreadEventCallback
377 // Registers a callback to run when a thread is created
379 bool registerThreadEventCallback(BPatch_asyncEventType type,
380 BPatchAsyncThreadEventCallback cb);
382 // BPatch::removeThreadEventCallback
383 // Registers a callback to run when a thread is destroyed
385 bool removeThreadEventCallback(BPatch_asyncEventType type,
386 BPatchAsyncThreadEventCallback cb);
388 // BPatch::registerDynamicCallCallback
389 // Specifies a user-supplied function to be called when a dynamic call is
393 bool registerDynamicCallCallback(BPatchDynamicCallSiteCallback cb);
396 bool removeDynamicCallCallback(BPatchDynamicCallSiteCallback cb);
399 // BPatch::registerUserEventCallback
401 // Specifies a user defined function to call when a "user event"
402 // occurs, user events are trigger by calls to the function
403 // DYNINSTuserMessage(void *, int) in the runtime library.
405 // BPatchUserEventCallback is:
406 // void (*BPatchUserEventCallback)(void *msg, unsigned int msg_size);
409 bool registerUserEventCallback(BPatchUserEventCallback cb);
412 bool removeUserEventCallback(BPatchUserEventCallback cb);
414 // BPatch::registerSignalHandlerCallback
416 // If the mutator produces a signal matching an element of
417 // signal_numbers, the callback is invoked, returning the point
418 // that caused the exception, the signal number, and a Vector
419 // representing the address of signal handler(s) in the mutatee
420 // for the exception. In Windows this is the handler stack, each
421 // function of which is invoked until one is found that agrees to
422 // handle the exception. In Unix there will be at most one
423 // handler for the signal number, the handler registered with
424 // syscalls signal() or sigaction(), or the default system
425 // handler, in which case we return an empty vector.
427 bool registerSignalHandlerCallback(BPatchSignalHandlerCallback cb,
428 std::set<long> &signal_numbers);
429 bool registerSignalHandlerCallback(BPatchSignalHandlerCallback cb,
430 BPatch_Set<long> *signal_numbers);
432 bool removeSignalHandlerCallback(BPatchSignalHandlerCallback cb);
435 bool registerCodeDiscoveryCallback(BPatchCodeDiscoveryCallback cb);
437 bool removeCodeDiscoveryCallback(BPatchCodeDiscoveryCallback cb);
439 // BPatch::registerCodeOverwriteCallbacks
441 // Registers a callback at the beginning and end of overwrite events
443 bool registerCodeOverwriteCallbacks
444 (BPatchCodeOverwriteBeginCallback cbBegin,
445 BPatchCodeOverwriteEndCallback cbEnd);
448 // BPatch::getProcesses:
449 // Get a vector of all processes
451 BPatch_Vector<BPatch_process*> * getProcesses();
454 // General BPatch parameter settings:
457 // BPatch::setDebugParsing:
458 // Turn on/off parsing of debug section(s)
461 void setDebugParsing(bool x);
463 // BPatch::setBaseTrampDeletion:
464 // Turn on/off deletion of base tramp
467 void setBaseTrampDeletion(bool x);
469 // BPatch::setTypeChecking:
470 // Turn on/off type checking
473 void setTypeChecking(bool x);
476 void setInstrStackFrames(bool b);
479 bool getInstrStackFrames();
481 // BPatch::setTypeChecking:
482 // Turn on/off line info truncating
485 void truncateLineInfoFilenames(bool x);
487 // BPatch::setTrampRecursive:
488 // Turn on/off recursive trampolines
491 void setTrampRecursive(bool x);
493 // BPatch::setMergeTramp:
494 // Turn on/off merged base & mini-tramps
497 void setMergeTramp(bool x);
499 // BPatch::setSaveFPR:
500 // Turn on/off merged base & mini-tramps
503 void setSaveFPR(bool x);
505 // BPatch::forceSaveFPR:
506 // Force Turn on/off merged base & mini-tramps - ignores isConservative
509 void forceSaveFPR(bool x);
512 // BPatch::setForcedRelocation_NP:
513 // Turn on/off forced relocation of instrumted functions
516 void setForcedRelocation_NP(bool x);
518 // BPatch::setAutoRelocation_NP:
519 // Turn on/off function relocations, performed when necessary
522 void setAutoRelocation_NP(bool x);
524 // BPatch::setDelayedParsing:
525 // Turn on/off delayed parsing
528 void setDelayedParsing(bool x);
532 void setLivenessAnalysis(bool x);
535 void setLivenessAnalysisDepth(int x);
537 // BPatch::processCreate:
538 // Create a new mutatee process
540 BPatch_process * processCreate(const char *path,
542 const char **envp = NULL,
546 BPatch_hybridMode mode=BPatch_normalMode);
549 // BPatch::processAttach
550 // Attach to mutatee process
552 BPatch_process *processAttach(const char *path, int pid,
553 BPatch_hybridMode mode=BPatch_normalMode);
556 // BPatch::openBinary
557 // Open a binary for static instrumentation
559 // The second parameter really should be a boolean, but the value
560 // gets reset between the openBinary and openBinaryInt calls--is
564 BPatch_binaryEdit * openBinary(const char *path, bool openDependencies = false);
566 // BPatch::createEnum:
567 // Create Enum types.
570 BPatch_type *createEnum(const char * name, BPatch_Vector<char *> &elementNames,
571 BPatch_Vector<int> &elementIds);
573 // BPatch::createEnum:
574 // API selects elementIds
577 BPatch_type *createEnum(const char * name, BPatch_Vector<char *> &elementNames);
579 // BPatch::createStruct:
580 // Create Struct types.
583 BPatch_type *createStruct(const char * name, BPatch_Vector<char *> &fieldNames,
584 BPatch_Vector<BPatch_type *> &fieldTypes);
586 // BPatch::createUnion:
587 // Create Union types.
590 BPatch_type *createUnion(const char * name, BPatch_Vector<char *> &fieldNames,
591 BPatch_Vector<BPatch_type *> &fieldTypes);
593 // BPatch::createArray:
594 // Creates BPatch_array type or symtyperanges ( scalars with upper and
598 BPatch_type *createArray(const char * name, BPatch_type * ptr,
599 unsigned int low, unsigned int hi);
601 // BPatch::createPointer:
602 // Creates BPatch_pointer types
605 BPatch_type *createPointer(const char * name, BPatch_type * ptr,
606 int size = sizeof(void *));
608 // BPatch::createScalar:
609 // Creates BPatch_scalar types
612 BPatch_type *createScalar(const char * name, int size);
614 // BPatch::createTypedef:
618 BPatch_type *createTypedef(const char * name, BPatch_type * ptr);
620 // User programs are required to call pollForStatusChange or
621 // waitForStatusChange before user-level callback functions
622 // are executed (for example, fork, exit, or a library load).
624 // Non-blocking form; returns immediately if no callback is
625 // ready, or executes callback(s) then returns.
627 bool pollForStatusChange();
629 // Blocks until a callback is ready.
631 bool waitForStatusChange();
633 // For user programs that block on other things as well,
634 // we provide a (simulated) file descriptor that can be added
635 // to a poll or select fdset. When a callback is prepared the BPatch
636 // layer writes to this fd, thus making poll/select return. The user
637 // program should then call pollForStatusChange. The BPatch layer
638 // will handle clearing the file descriptor; all the program must do
639 // is call pollForStatusChange or waitForStatusChange.
641 int getNotificationFD();
643 // BPatch:: waitUntilStopped:
644 // Block until specified process has stopped.
647 bool waitUntilStopped(BPatch_thread *appThread);
649 // BPatch::getBPatchStatistics:
650 // Get Instrumentation statistics
653 BPatch_stats & getBPatchStatistics();
657 void getBPatchVersion(int &major, int &minor, int &subminor);
659 // These three should probably be moved into their own BPatch_* class.
660 // Perhaps BPatch_remoteDebug?
665 bool remoteConnect(BPatch_remoteHost &remote);
668 bool getPidList(BPatch_remoteHost &remote, BPatch_Vector<unsigned int> &pidlist);
671 bool getPidInfo(BPatch_remoteHost &remote, unsigned int pid, std::string &pidStr);
674 bool remoteDisconnect(BPatch_remoteHost &remote);
676 // BPatch::addNonReturningFunc:
677 // Globally specify that any function with a given name will not return
679 void addNonReturningFunc(std::string name);
687 #endif /* _BPatch_h_ */