xref: /openbsd-src/gnu/llvm/lldb/source/Plugins/Process/Linux/NativeProcessLinux.h (revision f6aab3d83b51b91c24247ad2c2573574de475a82)
1 //===-- NativeProcessLinux.h ---------------------------------- -*- C++ -*-===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 
9 #ifndef liblldb_NativeProcessLinux_H_
10 #define liblldb_NativeProcessLinux_H_
11 
12 #include <csignal>
13 #include <unordered_set>
14 
15 #include "lldb/Host/Debug.h"
16 #include "lldb/Host/HostThread.h"
17 #include "lldb/Host/linux/Support.h"
18 #include "lldb/Target/MemoryRegionInfo.h"
19 #include "lldb/Utility/ArchSpec.h"
20 #include "lldb/Utility/FileSpec.h"
21 #include "lldb/lldb-types.h"
22 
23 #include "IntelPTCollector.h"
24 #include "NativeThreadLinux.h"
25 #include "Plugins/Process/POSIX/NativeProcessELF.h"
26 #include "Plugins/Process/Utility/NativeProcessSoftwareSingleStep.h"
27 
28 namespace lldb_private {
29 class Status;
30 class Scalar;
31 
32 namespace process_linux {
33 /// \class NativeProcessLinux
34 /// Manages communication with the inferior (debugee) process.
35 ///
36 /// Upon construction, this class prepares and launches an inferior process
37 /// for debugging.
38 ///
39 /// Changes in the inferior process state are broadcasted.
40 class NativeProcessLinux : public NativeProcessELF,
41                            private NativeProcessSoftwareSingleStep {
42 public:
43   class Factory : public NativeProcessProtocol::Factory {
44   public:
45     llvm::Expected<std::unique_ptr<NativeProcessProtocol>>
46     Launch(ProcessLaunchInfo &launch_info, NativeDelegate &native_delegate,
47            MainLoop &mainloop) const override;
48 
49     llvm::Expected<std::unique_ptr<NativeProcessProtocol>>
50     Attach(lldb::pid_t pid, NativeDelegate &native_delegate,
51            MainLoop &mainloop) const override;
52 
53     Extension GetSupportedExtensions() const override;
54   };
55 
56   // NativeProcessProtocol Interface
57   Status Resume(const ResumeActionList &resume_actions) override;
58 
59   Status Halt() override;
60 
61   Status Detach() override;
62 
63   Status Signal(int signo) override;
64 
65   Status Interrupt() override;
66 
67   Status Kill() override;
68 
69   Status GetMemoryRegionInfo(lldb::addr_t load_addr,
70                              MemoryRegionInfo &range_info) override;
71 
72   Status ReadMemory(lldb::addr_t addr, void *buf, size_t size,
73                     size_t &bytes_read) override;
74 
75   Status WriteMemory(lldb::addr_t addr, const void *buf, size_t size,
76                      size_t &bytes_written) override;
77 
78   llvm::Expected<lldb::addr_t> AllocateMemory(size_t size,
79                                               uint32_t permissions) override;
80 
81   llvm::Error DeallocateMemory(lldb::addr_t addr) override;
82 
83   Status ReadMemoryTags(int32_t type, lldb::addr_t addr, size_t len,
84                         std::vector<uint8_t> &tags) override;
85 
86   Status WriteMemoryTags(int32_t type, lldb::addr_t addr, size_t len,
87                          const std::vector<uint8_t> &tags) override;
88 
89   size_t UpdateThreads() override;
90 
GetArchitecture()91   const ArchSpec &GetArchitecture() const override { return m_arch; }
92 
93   Status SetBreakpoint(lldb::addr_t addr, uint32_t size,
94                        bool hardware) override;
95 
96   Status RemoveBreakpoint(lldb::addr_t addr, bool hardware = false) override;
97 
98   void DoStopIDBumped(uint32_t newBumpId) override;
99 
100   Status GetLoadedModuleFileSpec(const char *module_path,
101                                  FileSpec &file_spec) override;
102 
103   Status GetFileLoadAddress(const llvm::StringRef &file_name,
104                             lldb::addr_t &load_addr) override;
105 
106   NativeThreadLinux *GetThreadByID(lldb::tid_t id);
107   NativeThreadLinux *GetCurrentThread();
108 
109   llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>>
GetAuxvData()110   GetAuxvData() const override {
111     return getProcFile(GetID(), "auxv");
112   }
113 
114   /// Tracing
115   /// These methods implement the jLLDBTrace packets
116   /// \{
117   llvm::Error TraceStart(llvm::StringRef json_request,
118                          llvm::StringRef type) override;
119 
120   llvm::Error TraceStop(const TraceStopRequest &request) override;
121 
122   llvm::Expected<llvm::json::Value>
123   TraceGetState(llvm::StringRef type) override;
124 
125   llvm::Expected<std::vector<uint8_t>>
126   TraceGetBinaryData(const TraceGetBinaryDataRequest &request) override;
127 
128   llvm::Expected<TraceSupportedResponse> TraceSupported() override;
129   /// }
130 
131   // Interface used by NativeRegisterContext-derived classes.
132   static Status PtraceWrapper(int req, lldb::pid_t pid, void *addr = nullptr,
133                               void *data = nullptr, size_t data_size = 0,
134                               long *result = nullptr);
135 
136   bool SupportHardwareSingleStepping() const;
137 
138   /// Writes a siginfo_t structure corresponding to the given thread ID to the
139   /// memory region pointed to by \p siginfo.
140   Status GetSignalInfo(lldb::tid_t tid, void *siginfo) const;
141 
142 protected:
143   llvm::Expected<llvm::ArrayRef<uint8_t>>
144   GetSoftwareBreakpointTrapOpcode(size_t size_hint) override;
145 
146   llvm::Expected<uint64_t> Syscall(llvm::ArrayRef<uint64_t> args);
147 
148 private:
149   MainLoop::SignalHandleUP m_sigchld_handle;
150   ArchSpec m_arch;
151   MainLoop& m_main_loop;
152 
153   LazyBool m_supports_mem_region = eLazyBoolCalculate;
154   std::vector<std::pair<MemoryRegionInfo, FileSpec>> m_mem_region_cache;
155 
156   lldb::tid_t m_pending_notification_tid = LLDB_INVALID_THREAD_ID;
157 
158   /// Inferior memory (allocated by us) and its size.
159   llvm::DenseMap<lldb::addr_t, lldb::addr_t> m_allocated_memory;
160 
161   // Private Instance Methods
162   NativeProcessLinux(::pid_t pid, int terminal_fd, NativeDelegate &delegate,
163                      const ArchSpec &arch, MainLoop &mainloop,
164                      llvm::ArrayRef<::pid_t> tids);
165 
166   // Returns a list of process threads that we have attached to.
167   static llvm::Expected<std::vector<::pid_t>> Attach(::pid_t pid);
168 
169   static Status SetDefaultPtraceOpts(const lldb::pid_t);
170 
171   void MonitorCallback(NativeThreadLinux &thread, WaitStatus status);
172 
173   void WaitForCloneNotification(::pid_t pid);
174 
175   void MonitorSIGTRAP(const siginfo_t &info, NativeThreadLinux &thread);
176 
177   void MonitorTrace(NativeThreadLinux &thread);
178 
179   void MonitorBreakpoint(NativeThreadLinux &thread);
180 
181   void MonitorWatchpoint(NativeThreadLinux &thread, uint32_t wp_index);
182 
183   void MonitorSignal(const siginfo_t &info, NativeThreadLinux &thread);
184 
185   bool HasThreadNoLock(lldb::tid_t thread_id);
186 
187   void StopTrackingThread(NativeThreadLinux &thread);
188 
189   /// Create a new thread.
190   ///
191   /// If process tracing is enabled and the thread can't be traced, then the
192   /// thread is left stopped with a \a eStopReasonProcessorTrace status, and
193   /// then the process is stopped.
194   ///
195   /// \param[in] resume
196   ///     If a tracing error didn't happen, then resume the thread after
197   ///     creation if \b true, or leave it stopped with SIGSTOP if \b false.
198   NativeThreadLinux &AddThread(lldb::tid_t thread_id, bool resume);
199 
200   /// Start tracing a new thread if process tracing is enabled.
201   ///
202   /// Trace mechanisms should modify this method to provide automatic tracing
203   /// for new threads.
204   Status NotifyTracersOfNewThread(lldb::tid_t tid);
205 
206   /// Stop tracing threads upon a destroy event.
207   ///
208   /// Trace mechanisms should modify this method to provide automatic trace
209   /// stopping for threads being destroyed.
210   Status NotifyTracersOfThreadDestroyed(lldb::tid_t tid);
211 
212   void NotifyTracersProcessWillResume() override;
213 
214   void NotifyTracersProcessDidStop() override;
215 
216   /// Writes the raw event message code (vis-a-vis PTRACE_GETEVENTMSG)
217   /// corresponding to the given thread ID to the memory pointed to by @p
218   /// message.
219   Status GetEventMessage(lldb::tid_t tid, unsigned long *message);
220 
221   void NotifyThreadDeath(lldb::tid_t tid);
222 
223   Status Detach(lldb::tid_t tid);
224 
225   // This method is requests a stop on all threads which are still running. It
226   // sets up a
227   // deferred delegate notification, which will fire once threads report as
228   // stopped. The
229   // triggerring_tid will be set as the current thread (main stop reason).
230   void StopRunningThreads(lldb::tid_t triggering_tid);
231 
232   // Notify the delegate if all threads have stopped.
233   void SignalIfAllThreadsStopped();
234 
235   // Resume the given thread, optionally passing it the given signal. The type
236   // of resume
237   // operation (continue, single-step) depends on the state parameter.
238   Status ResumeThread(NativeThreadLinux &thread, lldb::StateType state,
239                       int signo);
240 
241   void ThreadWasCreated(NativeThreadLinux &thread);
242 
243   void SigchldHandler();
244 
245   Status PopulateMemoryRegionCache();
246 
247   /// Manages Intel PT process and thread traces.
248   IntelPTCollector m_intel_pt_collector;
249 
250   // Handle a clone()-like event.
251   bool MonitorClone(NativeThreadLinux &parent, lldb::pid_t child_pid,
252                     int event);
253 };
254 
255 } // namespace process_linux
256 } // namespace lldb_private
257 
258 #endif // #ifndef liblldb_NativeProcessLinux_H_
259