1 //===-- ProcessFreeBSD.h ------------------------------------------*- C++
2 //-*-===//
3 //
4 //                     The LLVM Compiler Infrastructure
5 //
6 // This file is distributed under the University of Illinois Open Source
7 // License. See LICENSE.TXT for details.
8 //
9 //===----------------------------------------------------------------------===//
10 
11 #ifndef liblldb_ProcessFreeBSD_H_
12 #define liblldb_ProcessFreeBSD_H_
13 
14 #include "Plugins/Process/POSIX/ProcessMessage.h"
15 #include "lldb/Target/Process.h"
16 #include "lldb/Target/ThreadList.h"
17 #include <mutex>
18 #include <queue>
19 #include <set>
20 
21 class ProcessMonitor;
22 class FreeBSDThread;
23 
24 class ProcessFreeBSD : public lldb_private::Process {
25 
26 public:
27   //------------------------------------------------------------------
28   // Static functions.
29   //------------------------------------------------------------------
30   static lldb::ProcessSP
31   CreateInstance(lldb::TargetSP target_sp, lldb::ListenerSP listener_sp,
32                  const lldb_private::FileSpec *crash_file_path);
33 
34   static void Initialize();
35 
36   static void Terminate();
37 
38   static lldb_private::ConstString GetPluginNameStatic();
39 
40   static const char *GetPluginDescriptionStatic();
41 
42   //------------------------------------------------------------------
43   // Constructors and destructors
44   //------------------------------------------------------------------
45   ProcessFreeBSD(lldb::TargetSP target_sp, lldb::ListenerSP listener_sp,
46                  lldb::UnixSignalsSP &unix_signals_sp);
47 
48   ~ProcessFreeBSD();
49 
50   virtual lldb_private::Status WillResume() override;
51 
52   //------------------------------------------------------------------
53   // PluginInterface protocol
54   //------------------------------------------------------------------
55   virtual lldb_private::ConstString GetPluginName() override;
56 
57   virtual uint32_t GetPluginVersion() override;
58 
59 public:
60   //------------------------------------------------------------------
61   // Process protocol.
62   //------------------------------------------------------------------
63   void Finalize() override;
64 
65   bool CanDebug(lldb::TargetSP target_sp,
66                 bool plugin_specified_by_name) override;
67 
68   lldb_private::Status WillLaunch(lldb_private::Module *module) override;
69 
70   lldb_private::Status DoAttachToProcessWithID(
71       lldb::pid_t pid,
72       const lldb_private::ProcessAttachInfo &attach_info) override;
73 
74   lldb_private::Status
75   DoLaunch(lldb_private::Module *exe_module,
76            lldb_private::ProcessLaunchInfo &launch_info) override;
77 
78   void DidLaunch() override;
79 
80   lldb_private::Status DoResume() override;
81 
82   lldb_private::Status DoHalt(bool &caused_stop) override;
83 
84   lldb_private::Status DoDetach(bool keep_stopped) override;
85 
86   lldb_private::Status DoSignal(int signal) override;
87 
88   lldb_private::Status DoDestroy() override;
89 
90   void DoDidExec() override;
91 
92   void RefreshStateAfterStop() override;
93 
94   bool IsAlive() override;
95 
96   size_t DoReadMemory(lldb::addr_t vm_addr, void *buf, size_t size,
97                       lldb_private::Status &error) override;
98 
99   size_t DoWriteMemory(lldb::addr_t vm_addr, const void *buf, size_t size,
100                        lldb_private::Status &error) override;
101 
102   lldb::addr_t DoAllocateMemory(size_t size, uint32_t permissions,
103                                 lldb_private::Status &error) override;
104 
105   lldb_private::Status DoDeallocateMemory(lldb::addr_t ptr) override;
106 
107   virtual size_t
108   GetSoftwareBreakpointTrapOpcode(lldb_private::BreakpointSite *bp_site);
109 
110   lldb_private::Status
111   EnableBreakpointSite(lldb_private::BreakpointSite *bp_site) override;
112 
113   lldb_private::Status
114   DisableBreakpointSite(lldb_private::BreakpointSite *bp_site) override;
115 
116   lldb_private::Status EnableWatchpoint(lldb_private::Watchpoint *wp,
117                                         bool notify = true) override;
118 
119   lldb_private::Status DisableWatchpoint(lldb_private::Watchpoint *wp,
120                                          bool notify = true) override;
121 
122   lldb_private::Status GetWatchpointSupportInfo(uint32_t &num) override;
123 
124   lldb_private::Status GetWatchpointSupportInfo(uint32_t &num,
125                                                 bool &after) override;
126 
127   virtual uint32_t UpdateThreadListIfNeeded();
128 
129   bool UpdateThreadList(lldb_private::ThreadList &old_thread_list,
130                         lldb_private::ThreadList &new_thread_list) override;
131 
132   virtual lldb::ByteOrder GetByteOrder() const;
133 
134   lldb::addr_t GetImageInfoAddress() override;
135 
136   size_t PutSTDIN(const char *buf, size_t len,
137                   lldb_private::Status &error) override;
138 
139   const lldb::DataBufferSP GetAuxvData() override;
140 
141   //--------------------------------------------------------------------------
142   // ProcessFreeBSD internal API.
143 
144   /// Registers the given message with this process.
145   virtual void SendMessage(const ProcessMessage &message);
146 
GetMonitor()147   ProcessMonitor &GetMonitor() {
148     assert(m_monitor);
149     return *m_monitor;
150   }
151 
152   lldb_private::FileSpec
153   GetFileSpec(const lldb_private::FileAction *file_action,
154               const lldb_private::FileSpec &default_file_spec,
155               const lldb_private::FileSpec &dbg_pts_file_spec);
156 
157   /// Adds the thread to the list of threads for which we have received the
158   /// initial stopping signal.
159   /// The \p stop_tid parameter indicates the thread which the stop happened
160   /// for.
161   bool AddThreadForInitialStopIfNeeded(lldb::tid_t stop_tid);
162 
163   bool WaitingForInitialStop(lldb::tid_t stop_tid);
164 
165   virtual FreeBSDThread *CreateNewFreeBSDThread(lldb_private::Process &process,
166                                                 lldb::tid_t tid);
167 
168   static bool SingleStepBreakpointHit(
169       void *baton, lldb_private::StoppointCallbackContext *context,
170       lldb::user_id_t break_id, lldb::user_id_t break_loc_id);
171 
172   lldb_private::Status SetupSoftwareSingleStepping(lldb::tid_t tid);
173 
174   lldb_private::Status SetSoftwareSingleStepBreakpoint(lldb::tid_t tid,
175                                                        lldb::addr_t addr);
176 
177   bool IsSoftwareStepBreakpoint(lldb::tid_t tid);
178 
179   bool SupportHardwareSingleStepping() const;
180 
181   typedef std::vector<lldb::tid_t> tid_collection;
GetStepTids()182   tid_collection &GetStepTids() { return m_step_tids; }
183 
184 protected:
185   static const size_t MAX_TRAP_OPCODE_SIZE = 8;
186 
187   /// Target byte order.
188   lldb::ByteOrder m_byte_order;
189 
190   /// Process monitor;
191   ProcessMonitor *m_monitor;
192 
193   /// The module we are executing.
194   lldb_private::Module *m_module;
195 
196   /// Message queue notifying this instance of inferior process state changes.
197   std::recursive_mutex m_message_mutex;
198   std::queue<ProcessMessage> m_message_queue;
199 
200   /// Drive any exit events to completion.
201   bool m_exit_now;
202 
203   /// Returns true if the process has exited.
204   bool HasExited();
205 
206   /// Returns true if the process is stopped.
207   bool IsStopped();
208 
209   /// Returns true if at least one running is currently running
210   bool IsAThreadRunning();
211 
212   typedef std::map<lldb::addr_t, lldb::addr_t> MMapMap;
213   MMapMap m_addr_to_mmap_size;
214 
215   typedef std::set<lldb::tid_t> ThreadStopSet;
216   /// Every thread begins with a stop signal. This keeps track
217   /// of the threads for which we have received the stop signal.
218   ThreadStopSet m_seen_initial_stop;
219 
220   friend class FreeBSDThread;
221 
222   tid_collection m_suspend_tids;
223   tid_collection m_run_tids;
224   tid_collection m_step_tids;
225   std::map<lldb::tid_t, lldb::break_id_t> m_threads_stepping_with_breakpoint;
226 
227   int m_resume_signo;
228 };
229 
230 #endif // liblldb_ProcessFreeBSD_H_
231