Fix instrumentation regressions for libc-2.29 on ARM (#653)
[dyninst.git] / dyninstAPI / src / dynProcess.h
1 /*
2  * See the dyninst/COPYRIGHT file for copyright information.
3  * 
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.
9  * 
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.
15  * 
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.
20  * 
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.
25  * 
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
29  */
30
31 #ifndef DYNPROCESS_H
32 #define DYNPROCESS_H
33 /*
34  * pcProcess.h
35  *
36  * A class that encapsulates a ProcControlAPI Process for the rest of Dyninst.
37  */
38
39 #include <string>
40 #include <map>
41 #include <set>
42
43 #include "addressSpace.h"
44 #include "dynThread.h"
45 #include "pcEventHandler.h"
46 #include "inst.h"
47 #include "codeRange.h"
48 #include "infHeap.h"
49 #include "ast.h"
50 #include "syscallNotification.h"
51 #include "os.h"
52 #include "baseTramp.h"
53
54 #include "Symtab.h"
55
56 #include "symtabAPI/h/SymtabReader.h"
57 #include "PCProcess.h"
58 #include "dyninstAPI_RT/h/dyninstAPI_RT.h"
59 #include "stackwalk/h/walker.h"
60 #include "stackwalk/h/framestepper.h"
61 #include "stackwalk/h/symlookup.h"
62
63 #define RPC_LEAVE_AS_IS 0
64 #define RPC_RUN_WHEN_DONE 1
65 #define RPC_STOP_WHEN_DONE 2
66
67 class DynSymReaderFactory;
68 class PCEventMuxer;
69
70 class PCProcess : public AddressSpace {
71     // Why PCEventHandler is a friend
72     // 
73     // PCProcess needs two interfaces: one that the rest of Dyninst sees and
74     // one that can be used to update the state of the PCProcess during event
75     // handling.
76     //
77     // The argument for having two different interfaces is that it will keep
78     // process control internals from bleeding out into the rest of Dyninst.
79     // This allows changes to the internals to have relatively low impact on the
80     // rest of Dyninst
81     friend class PCEventHandler;
82         friend class PCEventMuxer; // Needed for some state queries that are protected
83         friend class HybridAnalysis;
84
85 public:
86     // The desired state of the process, as indicated by the user
87     typedef enum {
88         ps_stopped,
89         ps_running,
90     } processState_t;
91
92     // Process creation and control
93     static PCProcess *createProcess(const std::string file, pdvector<std::string> &argv,
94                                     BPatch_hybridMode analysisMode,
95                                     pdvector<std::string> &envp,
96                                     const std::string dir, int stdin_fd, int stdout_fd,
97                                     int stderr_fd);
98
99     static PCProcess *attachProcess(const std::string &progpath, int pid,
100                                     BPatch_hybridMode analysisMode);
101     ~PCProcess();
102
103     static std::string createExecPath(const std::string &file, const std::string &dir);
104     virtual bool getDyninstRTLibName();
105
106     bool continueProcess();
107     bool stopProcess();
108     bool terminateProcess();
109     bool detachProcess(bool cont);
110
111     // Process status
112     bool isBootstrapped() const; // true if Dyninst has finished it's initialization for the process
113     bool isAttached() const; // true if ok to operate on the process
114     bool isStopped() const; // true if the process is stopped
115     bool isForcedTerminating() const { return forcedTerminating_; } // true if we're in the middle of a forced termination
116     bool isTerminated() const; // true if the process is terminated ( either via normal exit or crash )
117     bool hasExitedNormally() const; // true if the process has exited (via a normal exit)
118     bool isExecing() const; // true if the process is in the middle of an exec
119     processState_t getDesiredProcessState() const;
120     void setDesiredProcessState(processState_t ps);
121
122     // Memory access
123     bool dumpCore(std::string coreFile); // platform-specific
124     bool writeDataSpace(void *inTracedProcess,
125                         u_int amount, const void *inSelf);
126     bool writeDataWord(void *inTracedProcess,
127                        u_int amount, const void *inSelf);
128     bool readDataSpace(const void *inTracedProcess, u_int amount,
129                        void *inSelf, bool displayErrMsg);
130     bool readDataWord(const void *inTracedProcess, u_int amount,
131                       void *inSelf, bool displayErrMsg);
132     bool writeTextSpace(void *inTracedProcess, u_int amount, const void *inSelf);
133     bool writeTextWord(void *inTracedProcess, u_int amount, const void *inSelf);
134     bool readTextSpace(const void *inTracedProcess, u_int amount,
135                        void *inSelf);
136     bool readTextWord(const void *inTracedProcess, u_int amount,
137                       void *inSelf);
138
139     unsigned getMemoryPageSize() const;
140
141     typedef ProcControlAPI::Process::mem_perm PCMemPerm;
142     bool getMemoryAccessRights(Address start,  PCMemPerm& rights);
143     bool setMemoryAccessRights(Address start,  size_t size, PCMemPerm  rights);
144     void changeMemoryProtections(Address addr, size_t size, PCMemPerm  rights,
145                                  bool setShadow);
146
147 public:
148
149     // Process properties and fields
150     PCThread *getInitialThread() const;
151     PCThread *getThread(dynthread_t tid) const;
152     void getThreads(std::vector<PCThread* > &threads) const;
153     void addThread(PCThread *thread);
154     bool removeThread(dynthread_t tid);
155
156     int getPid() const;
157     unsigned getAddressWidth() const;
158     bool wasRunningWhenAttached() const;
159     bool wasCreatedViaAttach() const;
160     bool wasCreatedViaFork() const;
161     PCEventHandler *getPCEventHandler() const;
162     int incrementThreadIndex();
163
164     // Stackwalking
165     bool walkStacks(pdvector<pdvector<Frame> > &stackWalks);
166     bool getAllActiveFrames(pdvector<Frame> &activeFrames);
167
168     // Inferior Malloc
169     Address inferiorMalloc(unsigned size, inferiorHeapType type=anyHeap,
170                            Address near_=0, bool *err=NULL);
171     void inferiorMallocConstraints(Address near, Address &lo, Address &hi,
172                                    inferiorHeapType /* type */); // platform-specific
173     virtual void inferiorFree(Dyninst::Address);
174     virtual bool inferiorRealloc(Dyninst::Address, unsigned int);
175
176     // Instrumentation support
177     bool mappedObjIsDeleted(mapped_object *obj);
178     void installInstrRequests(const pdvector<instMapping*> &requests);
179     Address getTOCoffsetInfo(Address dest); // platform-specific
180     Address getTOCoffsetInfo(func_instance *func); // platform-specific
181     bool getOPDFunctionAddr(Address &opdAddr); // architecture-specific
182
183     // iRPC interface
184     bool postIRPC(AstNodePtr action,
185                  void *userData,
186                  bool runProcessWhenDone,
187                  PCThread *thread,
188                  bool synchronous,
189                  void **result,
190                  bool userRPC,
191                  bool isMemAlloc = false,
192                  Address addr = 0);
193         bool postIRPC(void* buffer, 
194                 int size, 
195                 void* userData, 
196                 bool runProcessWhenDone, 
197                 PCThread* thread, 
198                 bool synchronous, 
199                 void** result, 
200                 bool userRPC, 
201                 bool isMemAlloc = false, 
202                 Address addr = 0);
203 private:
204         bool postIRPC_internal(void *buffer,
205                                unsigned size,
206                                unsigned breakOffset,
207                                Register resultReg,
208                                Address addr,
209                                void *userData,
210                                bool runProcessWhenDone,
211                                PCThread *thread,
212                                bool synchronous,
213                                bool userRPC,
214                                bool isMemAlloc,
215                                void **result);
216                                
217
218 public:
219     /////////////////////////////////////////////
220     // Begin Exploratory and Defensive mode stuff
221     /////////////////////////////////////////////
222     BPatch_hybridMode getHybridMode();
223
224 // TODO FIXME
225 #if defined(os_windows)
226     pdvector<func_instance *> initial_thread_functions;
227     bool setBeingDebuggedFlag(bool debuggerPresent);
228 #endif
229
230     // code overwrites
231     bool getOverwrittenBlocks
232       ( std::map<Address, unsigned char *>& overwrittenPages,//input
233         std::list<std::pair<Address,Address> >& overwrittenRegions,//output
234         std::list<block_instance *> &writtenBBIs);//output
235
236     bool getDeadCode
237     ( const std::list<block_instance*> &owBlocks, // input
238       std::set<block_instance*> &delBlocks, //output: Del(for all f)
239       std::map<func_instance*,set<block_instance*> > &elimMap, //output: elimF
240       std::list<func_instance*> &deadFuncs, //output: DeadF
241       std::map<func_instance*,block_instance*> &newFuncEntries); //output: newF
242
243     // synch modified mapped objects with current memory contents
244     mapped_object *createObjectNoFile(Address addr);
245     void updateCodeBytes( const std::list<std::pair<Address, Address> > &owRegions);
246
247     bool isRuntimeHeapAddr(Address addr) const;
248     bool isExploratoryModeOn() const;
249
250     bool hideDebugger(); // platform-specific
251     void flushAddressCache_RT(Address start = 0, unsigned size = 0);
252     void flushAddressCache_RT(codeRange *range) { 
253         flushAddressCache_RT(range->get_address(), range->get_size());
254     }
255
256     // Active instrumentation tracking
257     typedef std::pair<Address, Address> AddrPair;
258     typedef std::set<AddrPair> AddrPairSet;
259     typedef std::set<Address> AddrSet;
260
261     struct ActiveDefensivePad {
262         Address activePC;
263         Address padStart;
264         block_instance *callBlock;
265         block_instance *ftBlock;
266         ActiveDefensivePad(Address a, Address b, block_instance *c, block_instance *d)
267             : activePC(a), padStart(b), callBlock(c), ftBlock(d) {};
268     };
269     typedef std::list<ActiveDefensivePad> ADPList;
270
271     bool patchPostCallArea(instPoint *point);
272     func_instance *findActiveFuncByAddr(Address addr);
273
274     /////////////////////////////////////////////
275     // End Exploratory and Defensive mode stuff
276     /////////////////////////////////////////////
277
278     // No function is pushed onto return vector if address can't be resolved
279     // to a function
280     pdvector<func_instance *> pcsToFuncs(pdvector<Frame> stackWalk);
281
282     // architecture-specific
283     virtual bool hasBeenBound(const SymtabAPI::relocationEntry &entry, 
284                            func_instance *&target_pdf, Address base_addr);
285
286     // AddressSpace implementations //
287     virtual Address offset() const;
288     virtual Address length() const;
289     virtual Architecture getArch() const;
290     virtual bool multithread_capable(bool ignoreIfMtNotSet = false); // platform-specific
291     virtual bool multithread_ready(bool ignoreIfMtNotSet = false);
292     virtual bool needsPIC();
293     //virtual bool unregisterTrapMapping(Address from);
294     virtual void addTrap(Address from, Address to, codeGen &gen);
295     virtual void removeTrap(Address from);
296
297     // Miscellaneuous
298     void debugSuicide();
299     bool dumpImage(std::string outFile);
300
301     // Stackwalking internals
302     bool walkStack(pdvector<Frame> &stackWalk, PCThread *thread);
303     bool getActiveFrame(Frame &frame, PCThread *thread);
304
305     void addSignalHandler(Address, unsigned);
306     bool isInSignalHandler(Address addr);
307
308     bool bindPLTEntry(const SymtabAPI::relocationEntry &,
309                       Address,
310                       func_instance *, 
311                       Address);
312     bool supportsUserThreadEvents(); 
313
314 protected:
315     typedef enum {
316         bs_attached,
317         bs_readyToLoadRTLib,
318         bs_loadedRTLib,
319         bs_initialized // RT library has been loaded
320     } bootstrapState_t;
321     
322     typedef enum {
323         not_cached,
324         cached_mt_true,
325         cached_mt_false
326     } mt_cache_result_t;
327
328     static PCProcess *setupExecedProcess(PCProcess *proc, std::string execPath);
329
330     // Process create/exec constructor
331     PCProcess(ProcControlAPI::Process::ptr pcProc, std::string file,
332             BPatch_hybridMode analysisMode)
333         : pcProc_(pcProc),
334           parent_(NULL),
335           initialThread_(NULL), 
336           file_(file), 
337           attached_(true),
338           execing_(false),
339           exiting_(false),
340        forcedTerminating_(false),
341           runningWhenAttached_(false), 
342           createdViaAttach_(false),
343           processState_(ps_stopped),
344           bootstrapState_(bs_attached),
345           main_function_(NULL),
346           curThreadIndex_(0),
347           reportedEvent_(false),
348           savedPid_(pcProc->getPid()),
349           savedArch_(pcProc->getArchitecture()),
350           analysisMode_(analysisMode), 
351           RT_address_cache_addr_(0),
352           sync_event_id_addr_(0),
353           sync_event_arg1_addr_(0),
354           sync_event_arg2_addr_(0),
355           sync_event_arg3_addr_(0),
356           sync_event_breakpoint_addr_(0),
357           rt_trap_func_addr_(0),
358        thread_hash_tids(0),
359        thread_hash_indices(0),
360        thread_hash_size(0),
361           eventHandler_(NULL),
362           eventCount_(0),
363           tracedSyscalls_(NULL),
364           mt_cache_result_(not_cached),
365           isInDebugSuicide_(false),
366           irpcTramp_(NULL),
367           inEventHandling_(false),
368           stackwalker_(NULL)
369     {
370         irpcTramp_ = baseTramp::createForIRPC(this);
371     }
372
373     // Process attach constructor
374     PCProcess(ProcControlAPI::Process::ptr pcProc, BPatch_hybridMode analysisMode)
375         : pcProc_(pcProc),
376           parent_(NULL),
377           initialThread_(NULL), 
378           attached_(true), 
379           execing_(false),
380           exiting_(false),
381        forcedTerminating_(false),
382           runningWhenAttached_(false), 
383           createdViaAttach_(true),
384           processState_(ps_stopped),
385           bootstrapState_(bs_attached), 
386           main_function_(NULL),
387           curThreadIndex_(0),
388           reportedEvent_(false),
389           savedPid_(pcProc->getPid()),
390           savedArch_(pcProc->getArchitecture()),
391           analysisMode_(analysisMode), 
392           RT_address_cache_addr_(0),
393           sync_event_id_addr_(0),
394           sync_event_arg1_addr_(0),
395           sync_event_arg2_addr_(0),
396           sync_event_arg3_addr_(0),
397           sync_event_breakpoint_addr_(0),
398           rt_trap_func_addr_(0),
399        thread_hash_tids(0),
400        thread_hash_indices(0),
401        thread_hash_size(0),
402           eventHandler_(NULL),
403           eventCount_(0),
404           tracedSyscalls_(NULL),
405           mt_cache_result_(not_cached),
406           isInDebugSuicide_(false),
407           irpcTramp_(NULL),
408           inEventHandling_(false),
409           stackwalker_(NULL)
410     {
411         irpcTramp_ = baseTramp::createForIRPC(this);
412     }
413
414     static PCProcess *setupForkedProcess(PCProcess *parent, ProcControlAPI::Process::ptr pcProc);
415
416     // Process fork constructor
417     PCProcess(PCProcess *parent, ProcControlAPI::Process::ptr pcProc)
418         : pcProc_(pcProc),
419           parent_(parent),
420           initialThread_(NULL), // filled in during bootstrap
421           file_(parent->file_),
422           attached_(true), 
423           execing_(false),
424           exiting_(false),
425        forcedTerminating_(false),
426           runningWhenAttached_(false), 
427           createdViaAttach_(false),
428           processState_(ps_stopped),
429           bootstrapState_(bs_attached), 
430           main_function_(parent->main_function_),
431           curThreadIndex_(0), // threads are created from ProcControl threads
432           reportedEvent_(false),
433           savedPid_(pcProc->getPid()),
434           savedArch_(pcProc->getArchitecture()),
435           analysisMode_(parent->analysisMode_), 
436           RT_address_cache_addr_(parent->RT_address_cache_addr_),
437           sync_event_id_addr_(parent->sync_event_id_addr_),
438           sync_event_arg1_addr_(parent->sync_event_arg1_addr_),
439           sync_event_arg2_addr_(parent->sync_event_arg2_addr_),
440           sync_event_arg3_addr_(parent->sync_event_arg3_addr_),
441           sync_event_breakpoint_addr_(parent->sync_event_breakpoint_addr_),
442           rt_trap_func_addr_(parent->rt_trap_func_addr_),
443        thread_hash_tids(parent->thread_hash_tids),
444        thread_hash_indices(parent->thread_hash_indices),
445        thread_hash_size(parent->thread_hash_size),
446           eventHandler_(parent->eventHandler_),
447           eventCount_(0),
448           tracedSyscalls_(NULL), // filled after construction
449           mt_cache_result_(parent->mt_cache_result_),
450           isInDebugSuicide_(parent->isInDebugSuicide_),
451           inEventHandling_(false),
452           stackwalker_(NULL)
453     {
454         irpcTramp_ = baseTramp::createForIRPC(this);
455     }
456
457     // bootstrapping
458     bool bootstrapProcess();
459     bool hasReachedBootstrapState(bootstrapState_t state) const;
460     void setBootstrapState(bootstrapState_t newState);
461     bool createStackwalker();
462     bool createStackwalkerSteppers(); // platform-specific
463     void createInitialThreads();
464     bool createInitialMappedObjects();
465     bool getExecFileDescriptor(std::string filename,
466                                bool waitForTrap, // Should we wait for process init
467                                fileDescriptor &desc);
468     void findSignalHandler(mapped_object *obj);
469     void setMainFunction();
470     bool setAOut(fileDescriptor &desc);
471     bool hasPassedMain(); // OS-specific
472     bool insertBreakpointAtMain();
473     ProcControlAPI::Breakpoint::ptr getBreakpointAtMain() const;
474     bool removeBreakpointAtMain();
475     Address getLibcStartMainParam(PCThread *thread); // architecture-specific
476     bool copyDanglingMemory(PCProcess *parent);
477     void invalidateMTCache();
478
479     // RT library management
480     bool loadRTLib();
481
482     AstNodePtr createUnprotectStackAST(); // architecture-specific
483     bool setRTLibInitParams();
484     bool instrumentMTFuncs();
485     bool extractBootstrapStruct(DYNINST_bootstrapStruct *bs_record);
486     bool iRPCDyninstInit();
487
488
489     Address getRTEventBreakpointAddr();
490     Address getRTEventIdAddr();
491     Address getRTEventArg1Addr();
492     Address getRTEventArg2Addr();
493     Address getRTEventArg3Addr();
494     Address getRTTrapFuncAddr();
495
496     // Shared library managment
497     void addASharedObject(mapped_object *newObj);
498     void removeASharedObject(mapped_object *oldObj);
499
500     // Inferior heap management
501     void addInferiorHeap(mapped_object *obj);
502     bool skipHeap(const heapDescriptor &heap); // platform-specific
503     bool inferiorMallocDynamic(int size, Address lo, Address hi);
504
505     // platform-specific (TODO AIX is dataHeap, everything else is anyHeap)
506     inferiorHeapType getDynamicHeapType() const; 
507     
508     // Hybrid Mode
509     bool triggerStopThread(Address pointAddress, int callbackID, void *calculation);
510     Address stopThreadCtrlTransfer(instPoint *intPoint, Address target);
511     bool generateRequiredPatches(instPoint *callPt, AddrPairSet &);
512     void generatePatchBranches(AddrPairSet &);
513
514     // Event Handling
515     void triggerNormalExit(int exitcode);
516
517     // Misc
518
519     // platform-specific, populates the passed map, if the file descriptors differ
520     static void redirectFds(int stdin_fd, int stdout_fd, int stderr_fd, 
521             std::map<int, int> &result);
522
523     // platform-specific, sets LD_PRELOAD with RT library 
524     static bool setEnvPreload(pdvector<std::string> &envp, std::string fileName);
525
526     bool isInDebugSuicide() const;
527
528     // Event handling support
529     void setReportingEvent(bool b);
530     bool hasReportedEvent() const;
531     void setExecing(bool b);
532     bool isInEventHandling() const;
533     void setInEventHandling(bool b);
534     void setExiting(bool b);
535     bool isExiting() const;
536     bool hasPendingEvents();
537     bool hasRunningSyncRPC() const;
538         void addSyncRPCThread(Dyninst::ProcControlAPI::Thread::ptr thr);
539     void removeSyncRPCThread(Dyninst::ProcControlAPI::Thread::ptr thr);
540     bool continueSyncRPCThreads();
541
542     // ProcControl doesn't keep around a process's information after it exits.
543     // However, we allow a Dyninst user to query certain information out of
544     // an exited process. Just make sure no operations are attempted on the
545     // ProcControl process
546     void markExited();
547
548     // Debugging
549     bool setBreakpoint(Address addr);
550     void writeDebugDataSpace(void *inTracedProcess, u_int amount,
551             const void *inSelf);
552     bool launchDebugger();
553     bool startDebugger(); // platform-specific
554     static void initSymtabReader();
555
556     // Fields //
557
558     // Underlying ProcControl process
559     ProcControlAPI::Process::ptr pcProc_;
560     PCProcess *parent_;
561
562     // Corresponding threads
563     std::map<dynthread_t, PCThread *> threadsByTid_;
564     PCThread *initialThread_;
565
566     ProcControlAPI::Breakpoint::ptr mainBrkPt_;
567
568     // Properties
569     std::string file_;
570     bool attached_;
571     bool execing_;
572     bool exiting_;
573     bool forcedTerminating_;
574     bool runningWhenAttached_;
575     bool createdViaAttach_;
576     processState_t processState_;
577     bootstrapState_t bootstrapState_;
578     func_instance *main_function_;
579     int curThreadIndex_;
580     // true when Dyninst has reported an event to ProcControlAPI for this process
581     bool reportedEvent_; // indicates the process should remain stopped
582     int savedPid_; // ProcControl doesn't keep around Process objects after exit
583     Dyninst::Architecture savedArch_;
584
585     // Hybrid Analysis
586     BPatch_hybridMode analysisMode_;
587
588     // Active instrumentation tracking
589     codeRangeTree signalHandlerLocations_;
590     pdvector<mapped_object *> deletedObjects_;
591     std::vector<heapItem *> dyninstRT_heaps_;
592     Address RT_address_cache_addr_;
593
594     // Addresses of variables in RT library
595     Address sync_event_id_addr_;
596     Address sync_event_arg1_addr_;
597     Address sync_event_arg2_addr_;
598     Address sync_event_arg3_addr_;
599     Address sync_event_breakpoint_addr_;
600     Address rt_trap_func_addr_;
601     Address thread_hash_tids;
602     Address thread_hash_indices;
603     int thread_hash_size;
604
605     // The same PCEventHandler held by the BPatch layer
606     PCEventHandler *eventHandler_;
607     //Mutex<> eventCountLock_;
608     int eventCount_;
609
610     syscallNotification *tracedSyscalls_;
611
612     mt_cache_result_t mt_cache_result_;
613
614     bool isInDebugSuicide_; // Single stepping is only valid in this context
615
616     // Misc.
617     baseTramp *irpcTramp_;
618     bool inEventHandling_;
619         std::set<Dyninst::ProcControlAPI::Thread::ptr> syncRPCThreads_;
620     Dyninst::Stackwalker::Walker *stackwalker_;
621     static Dyninst::SymtabAPI::SymtabReaderFactory *symReaderFactory_;
622     std::map<Address, ProcControlAPI::Breakpoint::ptr> installedCtrlBrkpts;
623 };
624
625 class inferiorRPCinProgress : public codeRange {
626 public:
627     inferiorRPCinProgress() :
628         rpc(ProcControlAPI::IRPC::ptr()),
629         rpcStartAddr(0),
630         rpcCompletionAddr(0),
631         resultRegister(REG_NULL),
632         returnValue(NULL),
633         runProcWhenDone(false),
634         isComplete(false),
635         deliverCallbacks(false),
636         userData(NULL),
637                 thread(Dyninst::ProcControlAPI::Thread::ptr()),
638         synchronous(false),
639         memoryAllocated(false)
640     {}
641
642     virtual Address get_address() const { return rpc->getAddress(); }
643     virtual unsigned get_size() const { return (rpcCompletionAddr - rpc->getAddress())+1; }
644     virtual void *getPtrToInstruction(Address /*addr*/) const { assert(0); return NULL; }
645
646     ProcControlAPI::IRPC::ptr rpc;
647     Address rpcStartAddr;
648     Address rpcCompletionAddr;
649
650     Register resultRegister; // register that contains the return value
651     void *returnValue;
652
653     bool runProcWhenDone;
654     bool isComplete;
655     bool deliverCallbacks;
656     void *userData;
657         Dyninst::ProcControlAPI::Thread::ptr thread;
658     bool synchronous; // caller is responsible for cleaning up this object
659     bool memoryAllocated;
660 };
661
662 class signal_handler_location : public codeRange {
663 public:
664     signal_handler_location(Address addr, unsigned size) :
665         addr_(addr), size_(size) {}
666
667     Address get_address() const {
668         return addr_;
669     }
670     unsigned get_size() const {
671         return size_;
672     }
673
674 private:
675     Address addr_;
676     unsigned size_;
677 };
678
679 class StackwalkSymLookup : public Dyninst::Stackwalker::SymbolLookup {
680   private:
681     PCProcess *proc_;
682
683   public:
684     StackwalkSymLookup(PCProcess *pc);
685     virtual bool lookupAtAddr(Dyninst::Address addr,
686                               std::string &out_name,
687                               void* &out_value);
688     virtual ~StackwalkSymLookup();
689 };
690
691 class StackwalkInstrumentationHelper : public Dyninst::Stackwalker::DyninstDynamicHelper {
692   private:
693     PCProcess *proc_;
694
695   public:
696     StackwalkInstrumentationHelper(PCProcess *pc);
697     virtual bool isInstrumentation(Dyninst::Address ra, Dyninst::Address *orig_ra,
698                                    unsigned *stack_height, bool *aligned, bool *entryExit);
699     virtual ~StackwalkInstrumentationHelper();
700 };
701
702 class DynFrameHelper : public Dyninst::Stackwalker::FrameFuncHelper {
703   private:
704     PCProcess *proc_;
705
706   public:
707     DynFrameHelper(PCProcess *pc);
708     virtual Dyninst::Stackwalker::FrameFuncHelper::alloc_frame_t allocatesFrame(Address addr);
709     virtual ~DynFrameHelper();
710 };
711
712 class DynWandererHelper : public Dyninst::Stackwalker::WandererHelper {
713   private:
714     PCProcess *proc_;
715
716   public:
717     DynWandererHelper(PCProcess *pc);
718     virtual bool isPrevInstrACall(Address addr, Address &target);
719     virtual Dyninst::Stackwalker::WandererHelper::pc_state isPCInFunc(Address func_entry, Address pc);
720     virtual bool requireExactMatch();
721     virtual ~DynWandererHelper();
722 };
723
724 #endif