Convert Dyninst to use StackwalkerAPI
[dyninst.git] / dyninstAPI / src / pcProcess.h
1 /*
2  * Copyright (c) 1996-2010 Barton P. Miller
3  * 
4  * We provide the Paradyn Parallel Performance Tools (below
5  * described as "Paradyn") on an AS IS basis, and do not warrant its
6  * validity or performance.  We reserve the right to update, modify,
7  * or discontinue this software at any time.  We shall have no
8  * obligation to supply such updates or modifications or any other
9  * form of support to you.
10  * 
11  * By your use of Paradyn, you understand and agree that we (or any
12  * other person or entity with proprietary rights in Paradyn) are
13  * under no obligation to provide either maintenance services,
14  * update services, notices of latent defects, or correction of
15  * defects for Paradyn.
16  * 
17  * This library is free software; you can redistribute it and/or
18  * modify it under the terms of the GNU Lesser General Public
19  * License as published by the Free Software Foundation; either
20  * version 2.1 of the License, or (at your option) any later version.
21  * 
22  * This library is distributed in the hope that it will be useful,
23  * but WITHOUT ANY WARRANTY; without even the implied warranty of
24  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
25  * Lesser General Public License for more details.
26  * 
27  * You should have received a copy of the GNU Lesser General Public
28  * License along with this library; if not, write to the Free Software
29  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
30  */
31
32 #ifndef PCPROCESS_H
33 #define PCPROCESS_H
34 /*
35  * pcProcess.h
36  *
37  * A class that encapsulates a ProcControlAPI Process for the rest of Dyninst.
38  */
39
40 #include <string>
41 #include <map>
42 #include <set>
43
44 #include "addressSpace.h"
45 #include "pcThread.h"
46 #include "pcEventHandler.h"
47 #include "BPatch_hybridAnalysis.h"
48 #include "inst.h"
49 #include "codeRange.h"
50 #include "infHeap.h"
51 #include "ast.h"
52 #include "syscallNotification.h"
53 #include "os.h"
54 #include "baseTramp.h"
55
56 #include "Symtab.h"
57
58 #include "proccontrol/h/Process.h"
59 #include "dyninstAPI_RT/h/dyninstAPI_RT.h"
60 #include "stackwalk/h/walker.h"
61 #include "stackwalk/h/framestepper.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 typedef enum { vsys_unknown, vsys_unused, vsys_notfound, vsys_found } syscallStatus_t;
68
69 class multiTramp;
70 class bblInstance;
71
72 class PCProcess : public AddressSpace {
73     // Why PCEventHandler is a friend
74     // 
75     // PCProcess needs two interfaces: one that the rest of Dyninst sees and
76     // one that can be used to update the state of the PCProcess during event
77     // handling.
78     //
79     // The argument for having two different interfaces is that it will keep
80     // process control internals from bleeding out into the rest of Dyninst.
81     // This allows changes to the internals to have relatively low impact on the
82     // rest of Dyninst
83     friend class PCEventHandler;
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, PCEventHandler *eventHandler);
98
99     static PCProcess *attachProcess(const std::string &progpath, int pid,
100                                     BPatch_hybridMode analysisMode, 
101                                     PCEventHandler *eventHandler);
102     ~PCProcess();
103
104     static std::string createExecPath(const std::string &file, const std::string &dir);
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 isTerminated() const; // true if the process is terminated ( either via normal exit or crash )
116     bool hasExitedNormally() const; // true if the process has exited (via a normal exit)
117     bool isExecing() const; // true if the process is in the middle of an exec
118     processState_t getDesiredProcessState() const;
119     void setDesiredProcessState(processState_t ps);
120
121     // Memory access
122     bool dumpCore(const std::string coreFile); // platform-specific
123     bool writeDataSpace(void *inTracedProcess,
124                         u_int amount, const void *inSelf);
125     bool writeDataWord(void *inTracedProcess,
126                        u_int amount, const void *inSelf);
127     bool readDataSpace(const void *inTracedProcess, u_int amount,
128                        void *inSelf, bool displayErrMsg);
129     bool readDataWord(const void *inTracedProcess, u_int amount,
130                       void *inSelf, bool displayErrMsg);
131     bool writeTextSpace(void *inTracedProcess, u_int amount, const void *inSelf);
132     bool writeTextWord(void *inTracedProcess, u_int amount, const void *inSelf);
133     bool readTextSpace(const void *inTracedProcess, u_int amount,
134                        void *inSelf);
135     bool readTextWord(const void *inTracedProcess, u_int amount,
136                       void *inSelf);
137
138     // Process properties and fields
139     PCThread *getInitialThread() const;
140     PCThread *getThread(dynthread_t tid) const;
141     void getThreads(std::vector<PCThread* > &threads) const;
142     void addThread(PCThread *thread);
143     bool removeThread(dynthread_t tid);
144
145     int getPid() const;
146     unsigned getAddressWidth() const;
147     bool wasRunningWhenAttached() const;
148     bool wasCreatedViaAttach() const;
149     bool wasCreatedViaFork() const;
150     PCEventHandler *getPCEventHandler() const;
151     int incrementThreadIndex();
152
153     // Stackwalking
154     bool walkStacks(pdvector<pdvector<Frame> > &stackWalks);
155     bool getAllActiveFrames(pdvector<Frame> &activeFrames);
156
157     // Inferior Malloc
158     Address inferiorMalloc(unsigned size, inferiorHeapType type=anyHeap,
159                            Address near_=0, bool *err=NULL);
160     void inferiorMallocConstraints(Address near, Address &lo, Address &hi,
161                                    inferiorHeapType /* type */); // platform-specific
162     virtual void inferiorFree(Dyninst::Address);
163     virtual bool inferiorRealloc(Dyninst::Address, unsigned int);
164
165     // Instrumentation support
166     virtual void deleteGeneratedCode(generatedCodeObject *del);
167     bool mappedObjIsDeleted(mapped_object *obj);
168     void installInstrRequests(const pdvector<instMapping*> &requests);
169     bool uninstallMutations();
170     bool reinstallMutations();
171
172     // iRPC interface
173     bool postIRPC(AstNodePtr action,
174                  void *userData,
175                  bool runProcessWhenDone,
176                  PCThread *thread,
177                  bool synchronous,
178                  void **result,
179                  bool userRPC,
180                  bool isMemAlloc = false,
181                  Address addr = 0);
182
183     // Hybrid Mode
184     BPatch_hybridMode getHybridMode();
185
186     // platform-specific
187     int setMemoryAccessRights(Address start, Address size, int rights);
188
189     // code overwrites
190     bool getOverwrittenBlocks(std::map<Address, unsigned char *>& overwrittenPages,//input
191                               std::map<Address,Address>& overwrittenRegions,//output
192                               std::set<bblInstance *> &writtenBBIs); //output
193     bool getDeadCodeFuncs(std::set<bblInstance *> &deadBlocks, // input
194                           std::set<int_function*> &affectedFuncs, //output
195                           std::set<int_function*> &deadFuncs); //output
196     unsigned getMemoryPageSize() const;
197
198
199     // synch modified mapped objects with current memory contents
200     mapped_object *createObjectNoFile(Address addr);
201     void updateMappedFile(std::map<Dyninst::Address,unsigned char*>& owPages,
202                           std::map<Address,Address> owRegions);
203
204     bool isRuntimeHeapAddr(Address addr) const;
205     bool isExploratoryModeOn() const;
206
207     bool hideDebugger(); // platform-specific
208
209     // Active instrumentation tracking
210     int_function *findActiveFuncByAddr(Address addr);
211     void getActiveMultiMap(std::map<Address, multiTramp *> &map);
212     void updateActiveMultis();
213     void addActiveMulti(multiTramp *multi);
214     void fixupActiveStackTargets();
215     void invalidateActiveMultis() { isAMcacheValid_ = false; }
216
217     // No function is pushed onto return vector if address can't be resolved
218     // to a function
219     pdvector<int_function *> pcsToFuncs(pdvector<Frame> stackWalk);
220
221     // architecture-specific
222     virtual bool hasBeenBound(const SymtabAPI::relocationEntry &entry, 
223                            int_function *&target_pdf, Address base_addr);
224
225     // AddressSpace implementations //
226     virtual Address offset() const;
227     virtual Address length() const;
228     virtual Architecture getArch() const;
229     virtual bool multithread_capable(bool ignoreIfMtNotSet = false); // platform-specific
230     virtual bool multithread_ready(bool ignoreIfMtNotSet = false);
231     virtual bool needsPIC();
232
233     // Miscellaneuous
234     void debugSuicide();
235     bool dumpImage(std::string outFile);
236
237     Address setAOutLoadAddress(fileDescriptor &desc); // platform-specific
238
239     // Syscall tracing (all architecture specific)
240     bool getSysCallParameters(const ProcControlAPI::RegisterPool &regs, long *params, int numparams);
241     int getSysCallNumber(const ProcControlAPI::RegisterPool &regs);
242     long getSysCallReturnValue(const ProcControlAPI::RegisterPool &regs);
243     Address getSysCallProgramCounter(const ProcControlAPI::RegisterPool &regs);
244     bool isMmapSysCall(int callnum);
245     Offset getMmapLength(int, const ProcControlAPI::RegisterPool &regs);
246
247     // Stackwalking internals
248     bool walkStack(pdvector<Frame> &stackWalk, PCThread *thread);
249     bool getActiveFrame(Frame &frame, PCThread *thread);
250
251     Address getVsyscallText() { return vsyscall_text_; }
252     void setVsyscallText(Address addr) { vsyscall_text_ = addr; }
253     Address getVsyscallStart() { return vsyscall_start_; }
254     Dyninst::SymtabAPI::Symtab *getVsyscallObject() { return vsyscall_obj_; }
255     void setVsyscallObject(SymtabAPI::Symtab *obj) { vsyscall_obj_ = obj; }
256     void setVsyscallRange(Address start, Address end) 
257         { vsyscall_start_ = start; vsyscall_end_ = end; }
258     syscallStatus_t getVsyscallStatus() { return vsys_status_; }
259     void setVsyscallStatus(syscallStatus_t s) { vsys_status_ = s; }
260     Address getVsyscallEnd() { return vsyscall_end_; }
261
262     void addSignalHandler(Address, unsigned);
263     bool isInSignalHandler(Address addr);
264     bool readAuxvInfo();
265
266 protected:
267     typedef enum {
268         bs_attached,
269         bs_readyToLoadRTLib,
270         bs_initialized // RT library has been loaded
271     } bootstrapState_t;
272     
273     typedef enum {
274         not_cached,
275         cached_mt_true,
276         cached_mt_false
277     } mt_cache_result_t;
278
279     static PCProcess *setupExecedProcess(PCProcess *proc, std::string execPath);
280
281     // Process create/exec constructor
282     PCProcess(ProcControlAPI::Process::ptr pcProc, std::string file,
283             BPatch_hybridMode analysisMode, PCEventHandler *eventHandler)
284         : pcProc_(pcProc),
285           parent_(NULL),
286           initialThread_(NULL), 
287           file_(file), 
288           attached_(true),
289           execing_(false),
290           exiting_(false),
291           runningWhenAttached_(false), 
292           createdViaAttach_(false),
293           processState_(ps_stopped),
294           bootstrapState_(bs_attached),
295           main_function_(NULL),
296           curThreadIndex_(0),
297           reportedEvent_(false),
298           savedPid_(pcProc->getPid()),
299           analysisMode_(analysisMode), 
300           memoryPageSize_(0),
301           isAMcacheValid_(false),
302           sync_event_id_addr_(0),
303           sync_event_arg1_addr_(0),
304           sync_event_arg2_addr_(0),
305           sync_event_arg3_addr_(0),
306           sync_event_breakpoint_addr_(0),
307           eventHandler_(eventHandler),
308           eventCount_(0),
309           tracedSyscalls_(NULL),
310           rtLibLoadHeap_(0),
311           mt_cache_result_(not_cached),
312           isInDebugSuicide_(false),
313           vsyscall_text_(0),
314           vsyscall_start_(0),
315           vsyscall_obj_(NULL),
316           vsyscall_end_(0),
317           vsys_status_(vsys_unknown),
318           auxv_parser_(NULL),
319           irpcTramp_(NULL),
320           inEventHandling_(false),
321           stackwalker_(NULL)
322     {
323         irpcTramp_ = new baseTramp(NULL, callUnset);
324         irpcTramp_->setRecursive(true);
325         irpcTramp_->setIRPCTramp(true);
326     }
327
328     // Process attach constructor
329     PCProcess(ProcControlAPI::Process::ptr pcProc, BPatch_hybridMode analysisMode,
330             PCEventHandler *eventHandler)
331         : pcProc_(pcProc),
332           parent_(NULL),
333           initialThread_(NULL), 
334           attached_(true), 
335           execing_(false),
336           exiting_(false),
337           runningWhenAttached_(false), 
338           createdViaAttach_(true),
339           processState_(ps_stopped),
340           bootstrapState_(bs_attached), 
341           main_function_(NULL),
342           curThreadIndex_(0),
343           reportedEvent_(false),
344           savedPid_(pcProc->getPid()),
345           analysisMode_(analysisMode), 
346           memoryPageSize_(0),
347           isAMcacheValid_(false),
348           sync_event_id_addr_(0),
349           sync_event_arg1_addr_(0),
350           sync_event_arg2_addr_(0),
351           sync_event_arg3_addr_(0),
352           sync_event_breakpoint_addr_(0),
353           eventHandler_(eventHandler),
354           eventCount_(0),
355           tracedSyscalls_(NULL),
356           rtLibLoadHeap_(0),
357           mt_cache_result_(not_cached),
358           isInDebugSuicide_(false),
359           vsyscall_text_(0),
360           vsyscall_start_(0),
361           vsyscall_obj_(NULL),
362           vsyscall_end_(0),
363           vsys_status_(vsys_unknown),
364           auxv_parser_(NULL),
365           irpcTramp_(NULL),
366           inEventHandling_(false),
367           stackwalker_(NULL)
368     {
369         irpcTramp_ = new baseTramp(NULL, callUnset);
370         irpcTramp_->setRecursive(true);
371         irpcTramp_->setIRPCTramp(true);
372     }
373
374     static PCProcess *setupForkedProcess(PCProcess *parent, ProcControlAPI::Process::ptr pcProc);
375
376     // Process fork constructor
377     PCProcess(PCProcess *parent, ProcControlAPI::Process::ptr pcProc)
378         : pcProc_(pcProc),
379           parent_(parent),
380           initialThread_(NULL), // filled in during bootstrap
381           file_(parent->file_),
382           attached_(true), 
383           execing_(false),
384           exiting_(false),
385           runningWhenAttached_(false), 
386           createdViaAttach_(false),
387           processState_(ps_stopped),
388           bootstrapState_(bs_attached), 
389           main_function_(parent->main_function_),
390           curThreadIndex_(0), // threads are created from ProcControl threads
391           reportedEvent_(false),
392           savedPid_(pcProc->getPid()),
393           analysisMode_(parent->analysisMode_), 
394           memoryPageSize_(parent->memoryPageSize_),
395           isAMcacheValid_(parent->isAMcacheValid_),
396           sync_event_id_addr_(parent->sync_event_id_addr_),
397           sync_event_arg1_addr_(parent->sync_event_arg1_addr_),
398           sync_event_arg2_addr_(parent->sync_event_arg2_addr_),
399           sync_event_arg3_addr_(parent->sync_event_arg3_addr_),
400           sync_event_breakpoint_addr_(parent->sync_event_breakpoint_addr_),
401           eventHandler_(parent->eventHandler_),
402           eventCount_(0),
403           tracedSyscalls_(NULL), // filled after construction
404           rtLibLoadHeap_(parent->rtLibLoadHeap_),
405           mt_cache_result_(parent->mt_cache_result_),
406           isInDebugSuicide_(parent->isInDebugSuicide_),
407           vsyscall_text_(parent->vsyscall_text_),
408           vsyscall_start_(parent->vsyscall_start_),
409           vsyscall_obj_(parent->vsyscall_obj_),
410           vsyscall_end_(parent->vsyscall_end_),
411           vsys_status_(parent->vsys_status_),
412           auxv_parser_(parent->auxv_parser_),
413           irpcTramp_(NULL), // filled after construction
414           inEventHandling_(false)
415     {
416     }
417
418     // bootstrapping
419     bool bootstrapProcess();
420     bool hasReachedBootstrapState(bootstrapState_t state) const;
421     void setBootstrapState(bootstrapState_t newState);
422     void createInitialThreads();
423     bool createInitialMappedObjects();
424     bool getExecFileDescriptor(std::string filename,
425                                bool waitForTrap, // Should we wait for process init
426                                fileDescriptor &desc);
427     void findSignalHandler(mapped_object *obj);
428     void setMainFunction();
429     bool setAOut(fileDescriptor &desc);
430     bool hasPassedMain(); // OS-specific
431     bool insertBreakpointAtMain();
432     ProcControlAPI::Breakpoint::ptr getBreakpointAtMain() const;
433     bool removeBreakpointAtMain();
434     Address getLibcStartMainParam(PCThread *thread); // architecture-specific
435     bool copyDanglingMemory(PCProcess *parent);
436
437     // RT library management
438     bool loadRTLib();
439     AstNodePtr createLoadRTAST(); // architecture-specific
440     AstNodePtr createUnprotectStackAST(); // architecture-specific
441     bool setRTLibInitParams();
442     bool instrumentMTFuncs();
443     bool initTrampGuard();
444     Address findFunctionToHijack(); // OS-specific
445     bool postRTLoadCleanup(); // architecture-specific
446     bool extractBootstrapStruct(DYNINST_bootstrapStruct *bs_record);
447     bool iRPCDyninstInit();
448     bool registerThread(PCThread *thread);
449     bool unregisterThread(dynthread_t tid);
450
451     Address getRTEventBreakpointAddr();
452     Address getRTEventIdAddr();
453     Address getRTEventArg1Addr();
454     Address getRTEventArg2Addr();
455     Address getRTEventArg3Addr();
456
457     // Shared library managment
458     void addASharedObject(mapped_object *newObj);
459     void removeASharedObject(mapped_object *oldObj);
460     bool usesDataLoadAddress() const; // OS-specific
461
462     // Inferior heap management
463     void addInferiorHeap(mapped_object *obj);
464     bool skipHeap(const heapDescriptor &heap); // platform-specific
465     bool inferiorMallocDynamic(int size, Address lo, Address hi);
466
467     // platform-specific (TODO AIX is dataHeap, everything else is anyHeap)
468     inferiorHeapType getDynamicHeapType() const; 
469     
470     // garbage collection instrumentation
471     void gcInstrumentation();
472     void gcInstrumentation(pdvector<pdvector<Frame> > &stackWalks);
473
474     // Hybrid Mode
475     bool triggerStopThread(Address pointAddress, int callbackID, void *calculation);
476     Address stopThreadCtrlTransfer(instPoint *intPoint, Address target);
477
478     // Event Handling
479     void triggerNormalExit(int exitcode);
480
481     // TODO this is temporary until ProcControl on Linux gives valid thread id's
482     PCThread *getThreadByLWP(Dyninst::LWP lwp);
483
484     // Misc
485
486     // platform-specific, true if the OS says the process is running
487     static bool getOSRunningState(int pid); 
488     
489     // platform-specific, populates the passed map, if the file descriptors differ
490     static void redirectFds(int stdin_fd, int stdout_fd, int stderr_fd, 
491             std::map<int, int> &result);
492
493     // platform-specific, sets LD_PRELOAD with RT library 
494     static bool setEnvPreload(pdvector<std::string> &envp, std::string fileName);
495
496     bool isInDebugSuicide() const;
497     void setReportingEvent(bool b);
498     bool hasReportedEvent() const;
499     void setExecing(bool b);
500     bool isInEventHandling() const;
501     void setInEventHandling(bool b);
502     void setExiting(bool b);
503     bool isExiting() const;
504     bool hasPendingEvents();
505     void incPendingEvents();
506     void decPendingEvents();
507     bool hasRunningSyncRPC() const;
508     void addSyncRPCThread(PCThread *thr);
509     void removeSyncRPCThread(PCThread *thr);
510     bool continueSyncRPCThreads();
511
512     // ProcControl doesn't keep around a process's information after it exits.
513     // However, we allow a Dyninst user to query certain information out of
514     // an exited process. Just make sure no operations are attempted on the
515     // ProcControl process
516     void markExited();
517
518     // Debugging
519     bool setBreakpoint(Address addr);
520
521     // Fields //
522
523     // Underlying ProcControl process
524     ProcControlAPI::Process::ptr pcProc_;
525     PCProcess *parent_;
526
527     // Corresponding threads
528     std::map<dynthread_t, PCThread *> threadsByTid_;
529     PCThread *initialThread_;
530
531     ProcControlAPI::Breakpoint::ptr mainBrkPt_;
532
533     // Properties
534     std::string file_;
535     bool attached_;
536     bool execing_;
537     bool exiting_;
538     bool runningWhenAttached_;
539     bool createdViaAttach_;
540     processState_t processState_;
541     bootstrapState_t bootstrapState_;
542     int_function *main_function_;
543     int curThreadIndex_;
544     // true when Dyninst has reported an event to ProcControlAPI for this process
545     bool reportedEvent_; // indicates the process should remain stopped
546     int savedPid_; // ProcControl doesn't keep around Process objects after exit
547
548     // Hybrid Analysis
549     BPatch_hybridMode analysisMode_;
550     int memoryPageSize_;
551
552     // Active instrumentation tracking
553     bool isAMcacheValid_;
554     std::set<multiTramp *> activeMultis_;
555     std::map<bblInstance *, Address> activeBBIs_;
556     std::map<int_function *, std::set<Address> *> am_funcRelocs_;
557
558     codeRangeTree signalHandlerLocations_;
559     pdvector<mapped_object *> deletedObjects_;
560     std::vector<heapItem *> dyninstRT_heaps_;
561     pdvector<generatedCodeObject *> pendingGCInstrumentation_;
562
563     // Addresses of variables in RT library
564     Address sync_event_id_addr_;
565     Address sync_event_arg1_addr_;
566     Address sync_event_arg2_addr_;
567     Address sync_event_arg3_addr_;
568     Address sync_event_breakpoint_addr_;
569
570     // The same PCEventHandler held by the BPatch layer
571     PCEventHandler *eventHandler_;
572     Mutex eventCountLock_;
573     int eventCount_;
574
575     syscallNotification *tracedSyscalls_;
576
577     // TODO remove when inferiorMalloc machinery uses ProcControlAPI 
578     // instead of the RT library
579     Address rtLibLoadHeap_;
580
581     mt_cache_result_t mt_cache_result_;
582
583     bool isInDebugSuicide_; // Single stepping is only valid in this context
584
585     // Stackwalking properties
586     Address vsyscall_text_;
587     Address vsyscall_start_;
588     SymtabAPI::Symtab *vsyscall_obj_;
589     Address vsyscall_end_;
590     syscallStatus_t vsys_status_;
591     AuxvParser *auxv_parser_;
592
593     // Misc.
594     baseTramp *irpcTramp_;
595     bool inEventHandling_;
596     std::set<PCThread *> syncRPCThreads_;
597     Dyninst::Stackwalker::Walker *stackwalker_;
598 };
599
600 class inferiorRPCinProgress : public codeRange {
601 public:
602     inferiorRPCinProgress() :
603         rpc(ProcControlAPI::IRPC::ptr()),
604         rpcStartAddr(0),
605         rpcCompletionAddr(0),
606         resultRegister(REG_NULL),
607         returnValue(NULL),
608         runProcWhenDone(false),
609         isComplete(false),
610         deliverCallbacks(false),
611         userData(NULL),
612         thread(NULL),
613         synchronous(false),
614         memoryAllocated(false)
615     {}
616
617     virtual Address get_address() const { return rpc->getAddress(); }
618     virtual unsigned get_size() const { return (rpcCompletionAddr - rpc->getAddress())+1; }
619     virtual void *getPtrToInstruction(Address /*addr*/) const { assert(0); return NULL; }
620
621     ProcControlAPI::IRPC::ptr rpc;
622     Address rpcStartAddr;
623     Address rpcCompletionAddr;
624
625     Register resultRegister; // register that contains the return value
626     void *returnValue;
627
628     bool runProcWhenDone;
629     bool isComplete;
630     bool deliverCallbacks;
631     void *userData;
632     PCThread *thread;
633     bool synchronous; // caller is responsible for cleaning up this object
634     bool memoryAllocated;
635 };
636
637 class signal_handler_location : public codeRange {
638 public:
639     signal_handler_location(Address addr, unsigned size) :
640         addr_(addr), size_(size) {}
641
642     Address get_address() const {
643         return addr_;
644     }
645     unsigned get_size() const {
646         return size_;
647     }
648
649 private:
650     Address addr_;
651     unsigned size_;
652 };
653
654 class StackwalkInstrumentationHelper : public Dyninst::Stackwalker::DyninstInstrHelper {
655   private:
656     PCProcess *proc_;
657
658   public:
659     StackwalkInstrumentationHelper(PCProcess *pc);
660     virtual bool isInstrumentation(Dyninst::Address ra, Dyninst::Address *orig_ra,
661                                    unsigned *stack_height, bool *entryExit);
662     virtual ~StackwalkInstrumentationHelper();
663 };
664
665 #endif