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 void
170         ChildFunc(const ProcessLaunchInfo &launch_info) LLVM_ATTRIBUTE_NORETURN;
171 
172         static Error
173         SetDefaultPtraceOpts(const lldb::pid_t);
174 
175         static bool
176         DupDescriptor(const FileSpec &file_spec, int fd, int flags);
177 
178         static void *
179         MonitorThread(void *baton);
180 
181         void
182         MonitorCallback(lldb::pid_t pid, bool exited, int signal, int status);
183 
184         void
185         WaitForNewThread(::pid_t tid);
186 
187         void
188         MonitorSIGTRAP(const siginfo_t &info, NativeThreadLinux &thread);
189 
190         void
191         MonitorTrace(NativeThreadLinux &thread);
192 
193         void
194         MonitorBreakpoint(NativeThreadLinux &thread);
195 
196         void
197         MonitorWatchpoint(NativeThreadLinux &thread, uint32_t wp_index);
198 
199         void
200         MonitorSignal(const siginfo_t &info, NativeThreadLinux &thread, bool exited);
201 
202         Error
203         SetupSoftwareSingleStepping(NativeThreadLinux &thread);
204 
205 #if 0
206         static ::ProcessMessage::CrashReason
207         GetCrashReasonForSIGSEGV(const siginfo_t *info);
208 
209         static ::ProcessMessage::CrashReason
210         GetCrashReasonForSIGILL(const siginfo_t *info);
211 
212         static ::ProcessMessage::CrashReason
213         GetCrashReasonForSIGFPE(const siginfo_t *info);
214 
215         static ::ProcessMessage::CrashReason
216         GetCrashReasonForSIGBUS(const siginfo_t *info);
217 #endif
218 
219         bool
220         HasThreadNoLock (lldb::tid_t thread_id);
221 
222         bool
223         StopTrackingThread (lldb::tid_t thread_id);
224 
225         NativeThreadLinuxSP
226         AddThread (lldb::tid_t thread_id);
227 
228         Error
229         GetSoftwareBreakpointPCOffset(uint32_t &actual_opcode_size);
230 
231         Error
232         FixupBreakpointPCAsNeeded(NativeThreadLinux &thread);
233 
234         /// Writes a siginfo_t structure corresponding to the given thread ID to the
235         /// memory region pointed to by @p siginfo.
236         Error
237         GetSignalInfo(lldb::tid_t tid, void *siginfo);
238 
239         /// Writes the raw event message code (vis-a-vis PTRACE_GETEVENTMSG)
240         /// corresponding to the given thread ID to the memory pointed to by @p
241         /// message.
242         Error
243         GetEventMessage(lldb::tid_t tid, unsigned long *message);
244 
245         void
246         NotifyThreadDeath (lldb::tid_t tid);
247 
248         Error
249         Detach(lldb::tid_t tid);
250 
251 
252         // This method is requests a stop on all threads which are still running. It sets up a
253         // deferred delegate notification, which will fire once threads report as stopped. The
254         // triggerring_tid will be set as the current thread (main stop reason).
255         void
256         StopRunningThreads(lldb::tid_t triggering_tid);
257 
258         // Notify the delegate if all threads have stopped.
259         void SignalIfAllThreadsStopped();
260 
261         // Resume the given thread, optionally passing it the given signal. The type of resume
262         // operation (continue, single-step) depends on the state parameter.
263         Error
264         ResumeThread(NativeThreadLinux &thread, lldb::StateType state, int signo);
265 
266         void
267         ThreadWasCreated(NativeThreadLinux &thread);
268 
269         void
270         SigchldHandler();
271     };
272 
273 } // namespace process_linux
274 } // namespace lldb_private
275 
276 #endif // #ifndef liblldb_NativeProcessLinux_H_
277