1 //===-- NativeProcessLinux.h ---------------------------------- -*- C++ -*-===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 
10 #ifndef liblldb_NativeProcessLinux_H_
11 #define liblldb_NativeProcessLinux_H_
12 
13 // C++ Includes
14 #include <unordered_set>
15 
16 // Other libraries and framework includes
17 #include "lldb/Core/ArchSpec.h"
18 #include "lldb/lldb-types.h"
19 #include "lldb/Host/Debug.h"
20 #include "lldb/Host/FileSpec.h"
21 #include "lldb/Host/HostThread.h"
22 #include "lldb/Target/MemoryRegionInfo.h"
23 
24 #include "lldb/Host/common/NativeProcessProtocol.h"
25 #include "NativeThreadLinux.h"
26 
27 namespace lldb_private {
28     class Error;
29     class Scalar;
30 
31 namespace process_linux {
32     /// @class NativeProcessLinux
33     /// @brief Manages communication with the inferior (debugee) process.
34     ///
35     /// Upon construction, this class prepares and launches an inferior process for
36     /// debugging.
37     ///
38     /// Changes in the inferior process state are broadcasted.
39     class NativeProcessLinux: public NativeProcessProtocol
40     {
41         friend Error
42         NativeProcessProtocol::Launch (ProcessLaunchInfo &launch_info,
43                 NativeDelegate &native_delegate,
44                 MainLoop &mainloop,
45                 NativeProcessProtocolSP &process_sp);
46 
47         friend Error
48         NativeProcessProtocol::Attach (lldb::pid_t pid,
49                 NativeProcessProtocol::NativeDelegate &native_delegate,
50                 MainLoop &mainloop,
51                 NativeProcessProtocolSP &process_sp);
52 
53     public:
54         // ---------------------------------------------------------------------
55         // NativeProcessProtocol Interface
56         // ---------------------------------------------------------------------
57         Error
58         Resume (const ResumeActionList &resume_actions) override;
59 
60         Error
61         Halt () override;
62 
63         Error
64         Detach () override;
65 
66         Error
67         Signal (int signo) override;
68 
69         Error
70         Interrupt () override;
71 
72         Error
73         Kill () override;
74 
75         Error
76         GetMemoryRegionInfo (lldb::addr_t load_addr, MemoryRegionInfo &range_info) override;
77 
78         Error
79         ReadMemory(lldb::addr_t addr, void *buf, size_t size, size_t &bytes_read) override;
80 
81         Error
82         ReadMemoryWithoutTrap(lldb::addr_t addr, void *buf, size_t size, size_t &bytes_read) override;
83 
84         Error
85         WriteMemory(lldb::addr_t addr, const void *buf, size_t size, size_t &bytes_written) override;
86 
87         Error
88         AllocateMemory(size_t size, uint32_t permissions, lldb::addr_t &addr) override;
89 
90         Error
91         DeallocateMemory (lldb::addr_t addr) override;
92 
93         lldb::addr_t
94         GetSharedLibraryInfoAddress () override;
95 
96         size_t
97         UpdateThreads () override;
98 
99         bool
100         GetArchitecture (ArchSpec &arch) const override;
101 
102         Error
103         SetBreakpoint (lldb::addr_t addr, uint32_t size, bool hardware) override;
104 
105         void
106         DoStopIDBumped (uint32_t newBumpId) override;
107 
108         Error
109         GetLoadedModuleFileSpec(const char* module_path, FileSpec& file_spec) override;
110 
111         Error
112         GetFileLoadAddress(const llvm::StringRef& file_name, lldb::addr_t& load_addr) override;
113 
114         NativeThreadLinuxSP
115         GetThreadByID(lldb::tid_t id);
116 
117         // ---------------------------------------------------------------------
118         // Interface used by NativeRegisterContext-derived classes.
119         // ---------------------------------------------------------------------
120         static Error
121         PtraceWrapper(int req,
122                       lldb::pid_t pid,
123                       void *addr = nullptr,
124                       void *data = nullptr,
125                       size_t data_size = 0,
126                       long *result = nullptr);
127 
128         bool
129         SupportHardwareSingleStepping() const;
130 
131     protected:
132         // ---------------------------------------------------------------------
133         // NativeProcessProtocol protected interface
134         // ---------------------------------------------------------------------
135         Error
136         GetSoftwareBreakpointTrapOpcode (size_t trap_opcode_size_hint, size_t &actual_opcode_size, const uint8_t *&trap_opcode_bytes) override;
137 
138     private:
139 
140         MainLoop::SignalHandleUP m_sigchld_handle;
141         ArchSpec m_arch;
142 
143         LazyBool m_supports_mem_region;
144         std::vector<MemoryRegionInfo> m_mem_region_cache;
145 
146         lldb::tid_t m_pending_notification_tid;
147 
148         // List of thread ids stepping with a breakpoint with the address of
149         // the relevan breakpoint
150         std::map<lldb::tid_t, lldb::addr_t> m_threads_stepping_with_breakpoint;
151 
152 
153         // ---------------------------------------------------------------------
154         // Private Instance Methods
155         // ---------------------------------------------------------------------
156         NativeProcessLinux ();
157 
158         Error
159         LaunchInferior(MainLoop &mainloop, ProcessLaunchInfo &launch_info);
160 
161         /// Attaches to an existing process.  Forms the
162         /// implementation of Process::DoAttach
163         void
164         AttachToInferior (MainLoop &mainloop, lldb::pid_t pid, Error &error);
165 
166         ::pid_t
167         Attach(lldb::pid_t pid, Error &error);
168 
169         static Error
170         SetDefaultPtraceOpts(const lldb::pid_t);
171 
172         static void *
173         MonitorThread(void *baton);
174 
175         void
176         MonitorCallback(lldb::pid_t pid, bool exited, int signal, int status);
177 
178         void
179         WaitForNewThread(::pid_t tid);
180 
181         void
182         MonitorSIGTRAP(const siginfo_t &info, NativeThreadLinux &thread);
183 
184         void
185         MonitorTrace(NativeThreadLinux &thread);
186 
187         void
188         MonitorBreakpoint(NativeThreadLinux &thread);
189 
190         void
191         MonitorWatchpoint(NativeThreadLinux &thread, uint32_t wp_index);
192 
193         void
194         MonitorSignal(const siginfo_t &info, NativeThreadLinux &thread, bool exited);
195 
196         Error
197         SetupSoftwareSingleStepping(NativeThreadLinux &thread);
198 
199 #if 0
200         static ::ProcessMessage::CrashReason
201         GetCrashReasonForSIGSEGV(const siginfo_t *info);
202 
203         static ::ProcessMessage::CrashReason
204         GetCrashReasonForSIGILL(const siginfo_t *info);
205 
206         static ::ProcessMessage::CrashReason
207         GetCrashReasonForSIGFPE(const siginfo_t *info);
208 
209         static ::ProcessMessage::CrashReason
210         GetCrashReasonForSIGBUS(const siginfo_t *info);
211 #endif
212 
213         bool
214         HasThreadNoLock (lldb::tid_t thread_id);
215 
216         bool
217         StopTrackingThread (lldb::tid_t thread_id);
218 
219         NativeThreadLinuxSP
220         AddThread (lldb::tid_t thread_id);
221 
222         Error
223         GetSoftwareBreakpointPCOffset(uint32_t &actual_opcode_size);
224 
225         Error
226         FixupBreakpointPCAsNeeded(NativeThreadLinux &thread);
227 
228         /// Writes a siginfo_t structure corresponding to the given thread ID to the
229         /// memory region pointed to by @p siginfo.
230         Error
231         GetSignalInfo(lldb::tid_t tid, void *siginfo);
232 
233         /// Writes the raw event message code (vis-a-vis PTRACE_GETEVENTMSG)
234         /// corresponding to the given thread ID to the memory pointed to by @p
235         /// message.
236         Error
237         GetEventMessage(lldb::tid_t tid, unsigned long *message);
238 
239         void
240         NotifyThreadDeath (lldb::tid_t tid);
241 
242         Error
243         Detach(lldb::tid_t tid);
244 
245 
246         // This method is requests a stop on all threads which are still running. It sets up a
247         // deferred delegate notification, which will fire once threads report as stopped. The
248         // triggerring_tid will be set as the current thread (main stop reason).
249         void
250         StopRunningThreads(lldb::tid_t triggering_tid);
251 
252         // Notify the delegate if all threads have stopped.
253         void SignalIfAllThreadsStopped();
254 
255         // Resume the given thread, optionally passing it the given signal. The type of resume
256         // operation (continue, single-step) depends on the state parameter.
257         Error
258         ResumeThread(NativeThreadLinux &thread, lldb::StateType state, int signo);
259 
260         void
261         ThreadWasCreated(NativeThreadLinux &thread);
262 
263         void
264         SigchldHandler();
265     };
266 
267 } // namespace process_linux
268 } // namespace lldb_private
269 
270 #endif // #ifndef liblldb_NativeProcessLinux_H_
271