Indirect tail calls can be PC-relative and should be treated as indirect calls during...
[dyninst.git] / proccontrol / h / PlatFeatures.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 #include "PCProcess.h"
32 #include "ProcessSet.h"
33
34 #include <list>
35 #include <vector>
36 #include <string>
37
38 #if !defined(PLATFEATURES_H_)
39 #define PLATFEATURES_H_
40
41 class int_process;
42 class sysv_process;
43 class thread_db_process;
44 class linux_process;
45 class int_libraryTracking;
46 class int_LWPTracking;
47 class int_threadTracking;
48 class int_followFork;
49 class int_multiToolControl;
50 class int_signalMask;
51 class int_callStackUnwinding;
52 class int_BGQData;
53 class int_remoteIO;
54 class int_memUsage;
55
56 namespace bgq {
57    class bgq_process;
58 };
59 class int_fileInfo;
60
61 //For sigset_t
62 #if !defined(_MSC_VER)
63 #include <signal.h>
64 #endif
65
66 namespace Dyninst {
67 namespace ProcControlAPI {
68
69 class PC_EXPORT LibraryTracking
70 {
71    friend class ::int_libraryTracking;
72    friend class ::int_process;
73   protected:
74    LibraryTracking(Process::ptr proc_);
75    ~LibraryTracking();
76    Process::weak_ptr proc;
77   public:
78    static void setDefaultTrackLibraries(bool b);
79    static bool getDefaultTrackLibraries();
80
81    bool setTrackLibraries(bool b) const;
82    bool getTrackLibraries() const;
83    bool refreshLibraries();
84 };
85
86 class PC_EXPORT LibraryTrackingSet
87 {
88    friend class ProcessSet;
89    friend class PSetFeatures;
90    friend class ::int_process;
91   protected:
92    LibraryTrackingSet(ProcessSet::ptr ps_);
93    ~LibraryTrackingSet();
94    ProcessSet::weak_ptr wps;
95   public:
96    bool setTrackLibraries(bool b) const;
97    bool refreshLibraries() const;
98 };
99
100 class PC_EXPORT LWPTracking
101 {
102    friend class ::linux_process;
103    friend class ::int_process;
104    friend class bgq::bgq_process;
105    friend class ::int_LWPTracking;
106   protected:
107    LWPTracking(Process::ptr proc_);
108    ~LWPTracking();
109    Process::weak_ptr proc;
110    static bool default_track_lwps;
111   public:
112    static void setDefaultTrackLWPs(bool b);
113    static bool getDefaultTrackLWPs();
114
115    void setTrackLWPs(bool b) const;
116    bool getTrackLWPs() const;
117    bool refreshLWPs();
118 };
119
120 class PC_EXPORT LWPTrackingSet
121 {
122    friend class ProcessSet;
123    friend class PSetFeatures;
124    friend class ::int_process;
125   protected:
126    LWPTrackingSet(ProcessSet::ptr ps_);
127    ~LWPTrackingSet();
128    ProcessSet::weak_ptr wps;
129   public:
130    bool setTrackLWPs(bool b) const;
131    bool refreshLWPs() const;
132 };
133
134 class PC_EXPORT ThreadTracking
135 {
136    friend class ::int_process;
137    friend class ::thread_db_process;
138    friend class ::int_threadTracking;
139   protected:
140    ThreadTracking(Process::ptr proc_);
141    ~ThreadTracking();
142    Process::weak_ptr proc;
143    static bool default_track_threads;
144   public:
145    static void setDefaultTrackThreads(bool b);
146    static bool getDefaultTrackThreads();
147
148    bool setTrackThreads(bool b) const;
149    bool getTrackThreads() const;
150    bool refreshThreads();
151 };
152
153 class PC_EXPORT ThreadTrackingSet
154 {
155    friend class ProcessSet;
156    friend class PSetFeatures;
157    friend class ::int_process;
158   protected:
159    ThreadTrackingSet(ProcessSet::ptr ps_);
160    ~ThreadTrackingSet();
161    ProcessSet::weak_ptr wps;
162   public:
163    bool setTrackThreads(bool b) const;
164    bool refreshThreads() const;
165 };
166
167 class PC_EXPORT FollowFork
168 {
169    friend class ::linux_process;
170    friend class ::int_process;
171    friend class ::int_followFork;
172   protected:
173    FollowFork(Process::ptr proc_);
174    ~FollowFork();
175    Process::weak_ptr proc;
176   public:
177
178    typedef enum {
179       None,                      //Fork tracking not available on this platform.
180       ImmediateDetach,           //Do not even attach to forked children.
181       DisableBreakpointsDetach,  //Remove inherited breakpoints from children, then detach.
182       Follow                     //Default. Attach and full control of forked children.
183    } follow_t;
184
185    static void setDefaultFollowFork(follow_t f);
186    static follow_t getDefaultFollowFork();
187
188    bool setFollowFork(follow_t b) const;
189    follow_t getFollowFork() const;
190   protected:
191    static follow_t default_should_follow_fork;
192 };
193
194 class PC_EXPORT FollowForkSet
195 {
196    friend class ProcessSet;
197    friend class PSetFeatures;
198   protected:
199    FollowForkSet(ProcessSet::ptr ps_);
200    ~FollowForkSet();
201    ProcessSet::weak_ptr wps;
202   public:
203    bool setFollowFork(FollowFork::follow_t f) const;
204 };
205
206 class PC_EXPORT CallStackCallback
207 {
208   private:
209    static const bool top_first_default_value = false;
210   public:
211    bool top_first;
212    CallStackCallback();
213    virtual bool beginStackWalk(Thread::ptr thr) = 0;
214    virtual bool addStackFrame(Thread::ptr thr, Dyninst::Address ra, Dyninst::Address sp, Dyninst::Address fp) = 0;
215    virtual void endStackWalk(Thread::ptr thr) = 0;
216    virtual ~CallStackCallback();
217 };
218
219 class PC_EXPORT CallStackUnwinding
220 {
221    friend class ::int_process;
222    friend class ::int_thread;
223    friend class ::int_callStackUnwinding;
224   private:
225    Thread::weak_ptr wt;
226   public:
227    CallStackUnwinding(Thread::ptr t);
228    virtual ~CallStackUnwinding();
229    bool walkStack(CallStackCallback *stk_cb) const;
230 };
231
232 class PC_EXPORT MemoryUsage
233 {
234    friend class ::int_process;
235    friend class ::int_memUsage;
236   private:
237    MemoryUsage(Process::ptr proc_);
238    ~MemoryUsage();
239    Process::weak_ptr proc;
240   public:
241    bool sharedUsed(unsigned long &sused) const;
242    bool heapUsed(unsigned long &hused) const;
243    bool stackUsed(unsigned long &sused) const;
244    bool resident(unsigned long &resident) const;
245 };
246
247 class PC_EXPORT MemoryUsageSet
248 {
249    friend class ProcessSet;
250    friend class PSetFeatures;
251   protected:
252    MemoryUsageSet(ProcessSet::ptr ps_);
253    ~MemoryUsageSet();
254    ProcessSet::weak_ptr wps;
255    typedef enum {
256       mus_shared = 0,
257       mus_heap,
258       mus_stack,
259       mus_resident
260    } mem_usage_t;
261    bool usedX(std::map<Process::const_ptr, unsigned long> &used, mem_usage_t mu) const;
262   public:
263    bool sharedUsed(std::map<Process::const_ptr, unsigned long> &used) const;
264    bool heapUsed(std::map<Process::const_ptr, unsigned long> &used) const;
265    bool stackUsed(std::map<Process::const_ptr, unsigned long> &used) const;
266    bool resident(std::map<Process::const_ptr, unsigned long> &res) const;
267 };
268
269 class PC_EXPORT CallStackUnwindingSet
270 {
271   private:
272    ThreadSet::weak_ptr wts;
273   public:
274    CallStackUnwindingSet(ThreadSet::ptr ts);
275    ~CallStackUnwindingSet();
276    bool walkStack(CallStackCallback *stk_cb);
277 };
278
279 class PC_EXPORT MultiToolControl
280 {
281    friend class bgq::bgq_process;
282    friend class ::int_process;
283    friend class ::int_multiToolControl;
284   public:
285    typedef unsigned int priority_t;
286   private:
287    Process::weak_ptr proc;
288   protected:
289    MultiToolControl(Process::ptr p);
290    ~MultiToolControl();
291    static std::string default_tool_name;
292    static priority_t default_tool_priority;
293   public:
294    static void setDefaultToolName(std::string name);
295    static void setDefaultToolPriority(priority_t p);
296    static std::string getDefaultToolName();
297    static priority_t getDefaultToolPriority();
298    
299    //Tool name and priority cannot be changed after process creation.
300    //To set these values, use the static methods to set the default,
301    // values, then trigger your attach/create operation.
302    std::string getToolName() const;
303    priority_t getToolPriority() const;
304 };
305
306 #if defined(_MSC_VER)
307 typedef void* dyn_sigset_t;
308 #else
309 typedef sigset_t dyn_sigset_t;
310 #endif
311
312 //On posix system, the sigset referenced below is a pointer to a sigset_t
313 class PC_EXPORT SignalMask
314 {
315    friend class ::int_process;
316    friend class ::int_signalMask;
317   protected:
318    static dyn_sigset_t default_sigset;
319    static bool sigset_initialized;
320   private:
321    Process::weak_ptr proc;
322    SignalMask(Process::ptr proc_);
323    ~SignalMask();
324   public:
325    static dyn_sigset_t getDefaultSigMask();
326    static void setDefaultSigMask(dyn_sigset_t s);
327    dyn_sigset_t getSigMask() const;
328    bool setSigMask(dyn_sigset_t s);
329 };
330
331 class PC_EXPORT BGQData
332 {
333    friend class ::int_process;
334    friend class bgq::bgq_process;
335    friend class ::int_BGQData;
336   protected:
337    static const unsigned int startup_timeout_sec_default = 45;
338    static const bool block_for_ca_default = true;
339    BGQData(Process::ptr proc_);
340    ~BGQData();
341    Process::weak_ptr proc;
342   public:
343    static void setStartupTimeout(unsigned int seconds);
344    static void setBlockForControlAuthority(bool block);
345    
346    //Five coordinates on torus (a, b, c, d, e), one on CN (t)
347    bool getProcCoordinates(unsigned &a, unsigned &b, unsigned &c, unsigned &d, unsigned &e, unsigned &t) const;
348
349    //All processes that share a CN will shared a ComputeNode ID
350    unsigned int getComputeNodeID() const;
351
352    bool getSharedMemRange(Dyninst::Address &start, Dyninst::Address &end) const;
353    bool getPersistantMemRange(Dyninst::Address &start, Dyninst::Address &end) const;
354    bool getHeapMemRange(Dyninst::Address &start, Dyninst::Address &end) const;
355 };
356
357 /**
358  * This struct is copied from the GLIBC sources for 'struct stat64'.  It is 
359  * recreated here because this header is supposed to compile without ifdefs 
360  * across platforms that may not have 'struct stat64'
361  **/
362 extern "C" struct stat64_ret_t {
363    unsigned long long st_dev;
364    unsigned long long st_ino;
365    unsigned int st_mode;
366    unsigned int st_nlink;
367    unsigned int st_uid;
368    unsigned int st_gid;
369    unsigned long long st_rdev;
370    unsigned short __pad2;
371    long long st_size;
372    int st_blksize;
373    long long st_blocks;
374    int st_atime_;
375    unsigned int st_atime_nsec;
376    int st_mtime_;
377    unsigned int st_mtime_nsec;
378    int st_ctime_;
379    unsigned int st_ctime_nsec;
380    unsigned int __unused4;
381    unsigned int __unused5;
382 };
383
384 typedef stat64_ret_t *stat64_ptr;
385 typedef boost::shared_ptr<int_fileInfo> int_fileInfo_ptr;
386
387 class RemoteIO;
388 class RemoteIOSet;
389
390 class FileInfo {
391    friend class ::int_remoteIO;
392    friend class RemoteIO;
393    friend class RemoteIOSet;
394   private:
395    mutable int_fileInfo_ptr info;
396    int_fileInfo_ptr getInfo() const;
397   public:
398    FileInfo(std::string fname);
399    FileInfo();
400    FileInfo(const FileInfo &fi);
401    ~FileInfo();
402    
403    std::string getFilename() const;
404    stat64_ptr getStatResults() const; //Filled in by getFileStatData
405 };
406
407 typedef std::multimap<Process::const_ptr, FileInfo> FileSet;
408
409 class PC_EXPORT RemoteIO
410 {
411   protected:
412    Process::weak_ptr proc;
413   public:
414    RemoteIO(Process::ptr proc);
415    virtual ~RemoteIO();
416
417    //Construct filesets based on filenames, without doing a getFileNames
418    // User is responsible for 'delete'ing the FileSet when done.
419    FileSet *getFileSet(std::string filename) const;
420    FileSet *getFileSet(const std::set<std::string> &filenames) const;
421    bool addToFileSet(std::string filename, FileSet *fs) const;
422   
423    //Fetches filenames from BGQ's persisent memory ramdisk
424    bool getFileNames(FileSet *result) const;
425
426    //Get data as per a stat system call, fill in the FileInfo objects
427    bool getFileStatData(FileSet *fset) const;
428
429    //These are whole file reads and produce EventAsyncFileRead callbacks
430    bool readFileContents(const FileSet *fset);
431 };
432
433 class PC_EXPORT RemoteIOSet
434 {
435   protected:
436    ProcessSet::weak_ptr pset;
437   public:
438    RemoteIOSet(ProcessSet::ptr procs_);
439    virtual ~RemoteIOSet();
440
441    FileSet *getFileSet(std::string filename);
442    FileSet *getFileSet(const std::set<std::string> &filenames);
443    bool addToFileSet(std::string filename, FileSet *fs);
444
445    bool getFileNames(FileSet *result);
446    bool getFileStatData(FileSet *fset);
447    bool readFileContents(const FileSet *fset);
448 };
449
450 }
451 }
452
453 #endif