Track whether we've detected that attach will break, and skip Dyninst attach mode...
[dyninst.git] / proccontrol / h / PCProcess.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 #if !defined(PROCESSPC_H_)
32 #define PROCESSPC_H_
33
34 #include <string>
35 #include <vector>
36 #include <map>
37 #include <set>
38 #include <iterator>
39
40 #include "dyntypes.h"
41 #include "dyn_regs.h"
42 #include "EventType.h"
43 #include "util.h"
44 #include "PCErrors.h"
45 #include "boost/checked_delete.hpp"
46 #include "boost/shared_ptr.hpp"
47 #include "boost/weak_ptr.hpp"
48 #include "boost/enable_shared_from_this.hpp"
49
50
51 class int_process;
52 class int_breakpoint;
53 class proc_exitstate;
54 class thread_exitstate;
55 class int_library;
56 class int_thread;
57 class int_threadPool;
58 class int_registerPool;
59 class rpc_wrapper;
60 class int_iRPC;
61 class int_notify;
62 class HandlerPool;
63 class MTLock;
64
65 #define PC_VERSION_8_0_0
66 #define PC_VERSION_8_1_0
67
68 #define pc_const_cast boost::const_pointer_cast
69
70 namespace Dyninst {
71
72 class SymbolReaderFactory;
73
74 namespace ProcControlAPI {
75
76    extern bool is_restricted_ptrace;
77   
78
79 class Process;
80 class ThreadPool;
81 class Thread;
82 class EventDecoder;
83 class EventGenerator;
84 class EventHandler;
85 class Event;
86 class RegisterPool;
87 class Breakpoint;
88 class ProcessSet;
89 class ThreadSet;
90 class LibraryTracking;
91 class ThreadTracking;
92 class LWPTracking;
93 class CallStackUnwinding;
94 class FollowFork;
95 class SignalMask;
96
97 class ExecFileInfo;
98
99 class PC_EXPORT Breakpoint 
100 {
101    friend class ::int_breakpoint;
102    friend void boost::checked_delete<Breakpoint>(Breakpoint *);
103    friend void boost::checked_delete<const Breakpoint>(const Breakpoint *);
104  private:
105    int_breakpoint *llbreakpoint_;
106    Breakpoint();
107    ~Breakpoint();
108  public:
109    static const int BP_X = 1;
110    static const int BP_W = 2;
111    static const int BP_R = 4;
112
113    int_breakpoint *llbp() const;
114    typedef boost::shared_ptr<Breakpoint> ptr;
115    typedef boost::shared_ptr<const Breakpoint> const_ptr;
116    typedef boost::weak_ptr<Breakpoint> weak_ptr;
117
118    static Breakpoint::ptr newBreakpoint();
119    static Breakpoint::ptr newTransferBreakpoint(Dyninst::Address to);
120    static Breakpoint::ptr newTransferOffsetBreakpoint(signed long shift);
121    static Breakpoint::ptr newHardwareBreakpoint(unsigned int mode, unsigned int size);
122
123    void *getData() const;
124    void setData(void *p) const;
125
126    bool isCtrlTransfer() const;
127    Dyninst::Address getToAddress() const;
128
129    void setSuppressCallbacks(bool);
130    bool suppressCallbacks() const;
131 };
132
133 class PC_EXPORT Library
134 {
135    friend class ::int_library;
136    friend void boost::checked_delete<Library>(Library *);
137    friend void boost::checked_delete<const Library>(const Library *);
138  private:
139    int_library *lib;
140    Library();
141    ~Library();
142  public:
143    typedef boost::shared_ptr<Library> ptr;
144    typedef boost::shared_ptr<const Library> const_ptr;
145
146    std::string getName() const;
147    Dyninst::Address getLoadAddress() const;
148    Dyninst::Address getDataLoadAddress() const;
149    Dyninst::Address getDynamicAddress() const;
150    int_library *debug() const { return lib; }
151    bool isSharedLib() const;
152
153    void *getData() const;
154    void setData(void *p) const;
155 };
156
157 class PC_EXPORT LibraryPool
158 {
159    friend class ::int_process;
160    friend class Dyninst::ProcControlAPI::Process;
161  private:
162    int_process *proc;
163    LibraryPool();
164    ~LibraryPool();
165  public:
166    class PC_EXPORT iterator  {
167       friend class Dyninst::ProcControlAPI::LibraryPool;
168    private:
169       std::set<int_library *>::iterator int_iter;
170    public:
171       iterator();
172       ~iterator();
173       Library::ptr operator*() const;
174       bool operator==(const iterator &i) const;
175       bool operator!=(const iterator &i) const;
176       LibraryPool::iterator operator++();
177       LibraryPool::iterator operator++(int);
178
179       typedef Library::ptr value_type;
180       typedef int difference_type;
181       typedef Library::ptr *pointer;
182       typedef Library::ptr &reference;
183       typedef std::forward_iterator_tag iterator_category;
184   };
185
186    class PC_EXPORT const_iterator  {
187      friend class Dyninst::ProcControlAPI::LibraryPool;
188   private:
189      std::set<int_library *>::iterator int_iter;
190   public:
191      const_iterator();
192      ~const_iterator();
193      Library::const_ptr operator*() const;
194      bool operator==(const const_iterator &i);
195      bool operator!=(const const_iterator &i);
196      LibraryPool::const_iterator operator++();
197      LibraryPool::const_iterator operator++(int);
198
199       typedef Library::const_ptr value_type;
200       typedef int difference_type;
201       typedef Library::const_ptr *pointer;
202       typedef Library::const_ptr &reference;
203       typedef std::forward_iterator_tag iterator_category;
204   };
205
206   iterator begin();
207   iterator end();
208   const_iterator begin() const;
209   const_iterator end() const;
210
211   size_t size() const;
212
213   Library::ptr getExecutable();
214   Library::const_ptr getExecutable() const;
215
216   Library::ptr getLibraryByName(std::string s);
217   Library::const_ptr getLibraryByName(std::string s) const;
218
219   iterator find(Library::ptr lib);
220   const_iterator find(Library::ptr lib) const;
221
222 };
223
224 class PC_EXPORT IRPC
225 {
226    friend class ::int_iRPC;
227    friend void boost::checked_delete<IRPC>(IRPC *);
228    friend void boost::checked_delete<const IRPC>(const IRPC *);
229  private:
230    rpc_wrapper *wrapper;
231    IRPC(rpc_wrapper *wrapper_);
232    ~IRPC();
233  public:
234          typedef enum {
235           Error = 0,
236           Created = 1,
237           Posted = 2,
238           Running = 3,
239           // Callback = 4,
240           Done = 5 } State;
241
242    typedef boost::shared_ptr<IRPC> ptr;
243    typedef boost::shared_ptr<const IRPC> const_ptr;
244    typedef boost::weak_ptr<IRPC> weak_ptr;
245    
246    static IRPC::ptr createIRPC(void *binary_blob, unsigned size, 
247                                bool non_blocking = false);
248    static IRPC::ptr createIRPC(void *binary_blob, unsigned size,
249                                Dyninst::Address addr, bool non_blocking = false);
250    static IRPC::ptr createIRPC(IRPC::ptr orig);
251    static IRPC::ptr createIRPC(IRPC::ptr orig, Address addr);
252    
253    rpc_wrapper *llrpc() const;
254
255    Dyninst::Address getAddress() const;
256    void *getBinaryCode() const;
257    unsigned getBinaryCodeSize() const;
258    unsigned long getID() const;
259    void setStartOffset(unsigned long);
260    unsigned long getStartOffset() const;
261    bool isBlocking() const;
262
263    // user-defined data retrievable during a callback
264    void *getData() const;
265    void setData(void *p) const;
266
267    State state() const;
268
269    // Continues the thread this RPC is running on.
270    // Useful if you don't know the thread assigned to an IRPC
271    bool continueStoppedIRPC();
272 };
273
274 class PC_EXPORT Process : public boost::enable_shared_from_this<Process>
275 {
276  private:
277    friend class ::int_process;
278    friend class ProcessSet;
279
280    int_process *llproc_;
281    proc_exitstate *exitstate_;
282    
283    Process();
284    ~Process();
285    friend void boost::checked_delete<Process>(Process *);
286    friend void boost::checked_delete<const Process>(const Process *);
287  public:
288    typedef boost::shared_ptr<Process> ptr;
289    typedef boost::shared_ptr<const Process> const_ptr;
290    typedef boost::weak_ptr<Process> weak_ptr;
291    typedef boost::weak_ptr<const Process> const_weak_ptr;
292
293    static void version(int& major, int& minor, int& maintenance);
294
295    //These four functions are not for end-users.  
296    int_process *llproc() const { return llproc_; }
297    proc_exitstate *exitstate() const { return exitstate_; }
298    void setLastError(ProcControlAPI::err_t err_code, const char *err_str) const;
299    void clearLastError() const;
300    
301    /**
302     * Threading modes control
303     **/
304    typedef enum {
305      NoThreads,
306      GeneratorThreading,
307      HandlerThreading,
308      CallbackThreading
309    } thread_mode_t;
310    static bool setThreadingMode(thread_mode_t tm);
311    static thread_mode_t getThreadingMode();
312
313    /**
314     * Create and attach to new processes
315     **/
316    static const std::map<int,int> emptyFDs;
317    static const std::vector<std::string> emptyEnvp;
318    static Process::ptr createProcess(std::string executable,
319                                      const std::vector<std::string> &argv,
320                                      const std::vector<std::string> &envp = emptyEnvp,
321                                      const std::map<int,int> &fds = emptyFDs);
322    static Process::ptr attachProcess(Dyninst::PID pid, std::string executable = "");
323
324    /**
325     * Event Management
326     **/
327    enum cb_action_t {
328      cbDefault,
329      cbThreadContinue,
330      cbThreadStop,
331      cbProcContinue,
332      cbProcStop
333    };
334    struct cb_ret_t {
335       cb_ret_t(cb_action_t p) : parent(p), child(cbDefault) {}
336       cb_ret_t(cb_action_t p, cb_action_t c) : parent(p), child(c) {}
337       cb_action_t parent;
338       cb_action_t child;
339    };
340    
341    //cb_func_t really takes an 'Event::const_ptr' as parameter, but this declaration
342    // defines the shared_ptr declaration due to Event::const_ptr not being defined yet.
343    typedef cb_ret_t(*cb_func_t)(boost::shared_ptr<const Event>);
344
345    static bool handleEvents(bool block);
346    static bool registerEventCallback(EventType evt, cb_func_t cbfunc);
347    static bool removeEventCallback(EventType evt, cb_func_t cbfunc);
348    static bool removeEventCallback(EventType evt);
349    static bool removeEventCallback(cb_func_t cbfunc);
350
351    // user-defined data retrievable during a callback
352    void *getData() const;
353    void setData(void *p) const;
354
355    Dyninst::PID getPid() const;
356
357    /**
358     * Threads
359     **/
360    const ThreadPool &threads() const;
361    ThreadPool &threads();
362    
363    /**
364     * Test state of process
365     **/
366    bool isTerminated() const;
367    bool isExited() const;
368    bool isCrashed() const;
369    bool isDetached() const;
370    int getExitCode() const;
371    int getCrashSignal() const;
372
373    bool hasStoppedThread() const;
374    bool hasRunningThread() const;
375    bool allThreadsStopped() const;
376    bool allThreadsRunning() const;
377    bool allThreadsRunningWhenAttached() const;
378
379    /**
380     * What capabilities do we have on this process
381     **/
382    static const unsigned int pc_read      = (1<<0);
383    static const unsigned int pc_write     = (1<<1);
384    static const unsigned int pc_irpc      = (1<<2);   
385    static const unsigned int pc_control   = (1<<3);
386    unsigned int getCapabilities() const;
387    
388    /**
389     * Queries for machine info
390     **/
391    Dyninst::Architecture getArchitecture() const;
392    Dyninst::OSType getOS() const;
393
394    /**
395     * Query what kind of events this process supports
396     **/
397    bool supportsLWPEvents() const;
398    bool supportsUserThreadEvents() const;
399    bool supportsFork() const;
400    bool supportsExec() const;
401
402    /**
403     * Control process
404     **/
405    bool continueProc();
406    bool stopProc();
407    bool detach(bool leaveStopped = false);
408    bool terminate();
409    bool temporaryDetach();
410    bool reAttach();
411
412    /**
413     * Memory management
414     **/
415    class PC_EXPORT mem_perm {
416        bool read;
417        bool write;
418        bool execute;
419
420        int permVal() const;
421
422    public:
423        mem_perm() : read(false), write(false), execute(false) {} 
424        mem_perm(const mem_perm& p) : read(p.read), write(p.write),
425                                      execute(p.execute) {}
426        mem_perm(bool r, bool w, bool x) : read(r), write(w), execute(x) {} 
427
428        bool getR() const { return read;    }
429        bool getW() const { return write;   }
430        bool getX() const { return execute; }
431
432        bool isNone() const { return !read && !write && !execute; }
433        bool isR()    const { return  read && !write && !execute; }
434        bool isX()    const { return !read && !write &&  execute; }
435        bool isRW()   const { return  read &&  write && !execute; }
436        bool isRX()   const { return  read && !write &&  execute; }
437        bool isRWX()  const { return  read &&  write &&  execute; }
438
439        mem_perm& setR() { read    = true;  return *this; }
440        mem_perm& setW() { write   = true;  return *this; }
441        mem_perm& setX() { execute = true;  return *this; }
442
443        mem_perm& clrR() { read    = false; return *this; }
444        mem_perm& clrW() { write   = false; return *this; }
445        mem_perm& clrX() { execute = false; return *this; }
446
447        bool operator< (const mem_perm& p) const;
448        bool operator==(const mem_perm& p) const;
449        bool operator!=(const mem_perm& p) const;
450
451        std::string getPermName() const;
452    };
453
454    unsigned getMemoryPageSize() const;
455
456    Dyninst::Address mallocMemory(size_t size);
457    Dyninst::Address mallocMemory(size_t size, Dyninst::Address addr);
458    bool freeMemory(Dyninst::Address addr);
459    bool writeMemory(Dyninst::Address addr, const void *buffer, size_t size) const;
460    bool readMemory(void *buffer, Dyninst::Address addr, size_t size) const;
461
462    bool writeMemoryAsync(Dyninst::Address addr, const void *buffer, size_t size, void *opaque_val = NULL) const;
463    bool readMemoryAsync(void *buffer, Dyninst::Address addr, size_t size, void *opaque_val = NULL) const;
464
465    /** 
466     * Currently Windows-only, needed for the test infrastructure but possibly useful elsewhere 
467     **/
468    Dyninst::Address findFreeMemory(size_t size);
469
470    bool getMemoryAccessRights(Dyninst::Address addr, size_t size,
471                               mem_perm& rights);
472    bool setMemoryAccessRights(Dyninst::Address addr, size_t size,
473                               mem_perm rights, mem_perm& oldRights);
474
475    // MemoryRegion.first = startAddr, MemoryRegion.second = endAddr
476    typedef std::pair<Dyninst::Address, Dyninst::Address> MemoryRegion;
477    bool findAllocatedRegionAround(Dyninst::Address addr, MemoryRegion& memRegion);
478
479    /**
480     * Libraries
481     **/
482    const LibraryPool &libraries() const;
483    LibraryPool &libraries();
484
485    // Cause a library to be loaded into the process (via black magic)
486    bool addLibrary(std::string libname);
487
488    /**
489     * Breakpoints
490     **/
491    bool addBreakpoint(Dyninst::Address addr, Breakpoint::ptr bp) const;
492    bool rmBreakpoint(Dyninst::Address addr, Breakpoint::ptr bp) const;
493    unsigned numHardwareBreakpointsAvail(unsigned mode);
494
495    /**
496     * Post IRPC.  Use continueProc/continueThread to run it,
497     * and handleEvents to wait for a blocking IRPC to complete
498     **/
499    bool postIRPC(IRPC::ptr irpc) const;
500    bool getPostedIRPCs(std::vector<IRPC::ptr> &rpcs) const;
501
502    /**
503     * Post, run, and wait for an IRPC to complete
504     **/
505         bool runIRPCSync(IRPC::ptr irpc);
506
507    /**
508     * Post and run an IRPC; user must wait for completion. 
509     **/
510         bool runIRPCAsync(IRPC::ptr irpc);
511
512    /**
513     * Symbol access
514     **/
515    void setSymbolReader(SymbolReaderFactory *reader) const;
516    SymbolReaderFactory *getSymbolReader() const;
517    static SymbolReaderFactory *getDefaultSymbolReader();
518    static void setDefaultSymbolReader(SymbolReaderFactory *reader);
519
520    /**
521     * Perform specific operations.  Interface objects will only be returned
522     * on appropriately supported platforms, others will return NULL.
523     **/
524    LibraryTracking *getLibraryTracking();
525    ThreadTracking *getThreadTracking();
526    LWPTracking *getLWPTracking();
527    FollowFork *getFollowFork();
528    SignalMask *getSignalMask();
529    const LibraryTracking *getLibraryTracking() const;
530    const ThreadTracking *getThreadTracking() const;
531    const LWPTracking *getLWPTracking() const;
532    const FollowFork *getFollowFork() const;
533    const SignalMask *getSignalMask() const;
534    
535    /**
536     * Errors that occured on this process
537     **/
538    ProcControlAPI::err_t getLastError() const;
539    const char *getLastErrorMsg() const;
540
541    /**
542     * Executable info
543     **/
544         ExecFileInfo* getExecutableInfo() const;
545 };
546
547 class PC_EXPORT Thread
548 {
549  protected:
550    friend class ::int_thread;
551    int_thread *llthread_;
552    thread_exitstate *exitstate_;
553
554    Thread();
555    ~Thread();
556    friend void boost::checked_delete<Thread>(Thread *);
557    friend void boost::checked_delete<const Thread>(const Thread *);
558
559  public:
560    typedef boost::shared_ptr<Thread> ptr;
561    typedef boost::shared_ptr<const Thread> const_ptr;
562    typedef boost::weak_ptr<Thread> weak_ptr;
563    typedef boost::weak_ptr<const Thread> const_weak_ptr;
564    int_thread *llthrd() const;
565    void setLastError(err_t ec, const char *es) const;
566
567    Dyninst::LWP getLWP() const;
568    Process::ptr getProcess();
569    Process::const_ptr getProcess() const;
570
571    bool isStopped() const;
572    bool isRunning() const;
573    bool isLive() const;
574    bool isDetached() const;
575    bool isInitialThread() const;
576
577    // Added for Windows. Windows creates internal threads which are bound to 
578    // the process but are used for OS-level work. We hide these from the user,
579    // but need to represent them in ProcControlAPI. 
580    bool isUser() const; 
581
582    bool stopThread();
583    bool continueThread();
584
585    void setSingleStepMode(bool s) const;
586    bool getSingleStepMode() const;
587
588    bool getRegister(Dyninst::MachRegister reg, Dyninst::MachRegisterVal &val) const;
589    bool getAllRegisters(RegisterPool &pool) const;
590    bool setRegister(Dyninst::MachRegister reg, Dyninst::MachRegisterVal val) const;
591    bool setAllRegisters(RegisterPool &pool) const;
592    bool getAllRegistersAsync(RegisterPool &pool, void *opaque_val = NULL) const;
593    bool setAllRegistersAsync(RegisterPool &pool, void *opaque_val = NULL) const;
594
595    /**
596     * User level thread info.  Only available after a UserThreadCreate event
597     **/
598    bool haveUserThreadInfo() const;
599    Dyninst::THR_ID getTID() const;
600    Dyninst::Address getStartFunction() const;
601    Dyninst::Address getStackBase() const;
602    unsigned long getStackSize() const;
603    Dyninst::Address getTLS() const;
604    Dyninst::Address getThreadInfoBlockAddr() const;
605
606    /**
607     * IRPC
608     **/
609    bool postIRPC(IRPC::ptr irpc) const;
610    bool runIRPCSync(IRPC::ptr irpc);
611    bool runIRPCAsync(IRPC::ptr irpc);
612
613    bool getPostedIRPCs(std::vector<IRPC::ptr> &rpcs) const;
614    IRPC::const_ptr getRunningIRPC() const;
615
616    /**
617     * Returns a stack unwinder on supported platforms (BlueGene/Q).
618     * Returns NULL on unsupported platforms
619     **/
620    CallStackUnwinding *getCallStackUnwinding();
621
622    void *getData() const;
623    void setData(void *p) const;
624 };
625
626 class PC_EXPORT ThreadPool
627 {
628  private:
629    friend class ::int_threadPool;
630    friend class Dyninst::ProcControlAPI::Process;
631    int_threadPool *threadpool;
632    ThreadPool();
633    ~ThreadPool();
634  public:
635    /**
636     * Iterators
637     **/
638    class PC_EXPORT iterator {
639       friend class Dyninst::ProcControlAPI::ThreadPool;
640    private:
641       static const int uninitialized_val = -1;
642       static const int end_val = -2;
643       int_threadPool *curp;
644       Thread::ptr curh;
645       int curi;
646    public:
647       iterator();
648       ~iterator();
649       Thread::ptr operator*() const;
650       bool operator==(const iterator &i);
651       bool operator!=(const iterator &i);
652       ThreadPool::iterator operator++();
653       ThreadPool::iterator operator++(int);
654    };
655    iterator begin();
656    iterator end();
657    iterator find(Dyninst::LWP lwp);
658
659    class PC_EXPORT const_iterator {
660       friend class Dyninst::ProcControlAPI::ThreadPool;
661    private:
662       static const int uninitialized_val = -1;
663       static const int end_val = -2;
664       int_threadPool *curp;
665       Thread::ptr curh;
666       int curi;
667    public:
668       const_iterator();
669       ~const_iterator();
670       Thread::const_ptr operator*() const;
671       bool operator==(const const_iterator &i);
672       bool operator!=(const const_iterator &i);
673       ThreadPool::const_iterator operator++();
674       ThreadPool::const_iterator operator++(int);
675
676           typedef Thread::const_ptr value_type;
677           typedef int difference_type;
678           typedef Thread::const_ptr *pointer;
679           typedef Thread::const_ptr &reference;
680           typedef std::forward_iterator_tag iterator_category;
681    };
682    const_iterator begin() const;
683    const_iterator end() const;
684    const_iterator find(Dyninst::LWP lwp) const;
685
686    size_t size() const;
687    Process::const_ptr getProcess() const;
688    Process::ptr getProcess();
689    Thread::const_ptr getInitialThread() const;
690    Thread::ptr getInitialThread();
691 };
692
693 class PC_EXPORT RegisterPool
694
695    friend class Dyninst::ProcControlAPI::Thread;
696    friend class Dyninst::ProcControlAPI::ThreadSet;
697  private:
698    int_registerPool *llregpool;
699  public:
700    RegisterPool();
701    RegisterPool(const RegisterPool &rp);
702    ~RegisterPool();
703    
704    class PC_EXPORT iterator {
705       friend class Dyninst::ProcControlAPI::RegisterPool;
706    private:
707       typedef std::map<Dyninst::MachRegister, Dyninst::MachRegisterVal>::iterator int_iter; 
708       int_iter i;
709       iterator(int_iter i_);
710    public:
711       iterator();
712       ~iterator();
713       std::pair<Dyninst::MachRegister, Dyninst::MachRegisterVal> operator*();
714       bool operator==(const iterator &i);
715       bool operator!=(const iterator &i);
716       RegisterPool::iterator operator++();
717       RegisterPool::iterator operator++(int);
718    };
719    iterator begin();
720    iterator end();
721    iterator find(Dyninst::MachRegister r);
722
723    class PC_EXPORT const_iterator {
724       friend class Dyninst::ProcControlAPI::RegisterPool;
725    private:
726       typedef std::map<Dyninst::MachRegister, Dyninst::MachRegisterVal>::const_iterator int_iter; 
727       int_iter i;
728       const_iterator(int_iter i_);
729    public:
730       const_iterator();
731       ~const_iterator();
732       std::pair<Dyninst::MachRegister, Dyninst::MachRegisterVal> operator*() const;
733       bool operator==(const const_iterator &i);
734       bool operator!=(const const_iterator &i);
735       RegisterPool::const_iterator operator++();
736       RegisterPool::const_iterator operator++(int);
737    };
738    const_iterator begin() const;
739    const_iterator end() const;
740    const_iterator find(Dyninst::MachRegister r) const;
741
742    Dyninst::MachRegisterVal& operator[](Dyninst::MachRegister r);
743    const Dyninst::MachRegisterVal& operator[](Dyninst::MachRegister r) const;
744
745    size_t size() const;
746    Thread::const_ptr getThread() const;
747    Thread::ptr getThread();
748 };
749
750 class PC_EXPORT EventNotify
751 {
752  private:
753    friend class ::int_notify;
754    int_notify *llnotify;
755    EventNotify();
756    ~EventNotify();
757  public:
758    typedef void (*notify_cb_t)();
759
760    int getFD();
761    void registerCB(notify_cb_t cb);
762    void removeCB(notify_cb_t cb);
763 };
764 PC_EXPORT EventNotify *evNotify();
765
766 class PC_EXPORT ExecFileInfo
767 {
768   public:
769         void* fileHandle;
770         void* processHandle;
771         Address fileBase;
772 };
773
774
775 }
776 }
777
778 #endif