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/Host/Debug.h"
19 #include "lldb/Host/FileSpec.h"
20 #include "lldb/Host/HostThread.h"
21 #include "lldb/Target/MemoryRegionInfo.h"
22 #include "lldb/lldb-types.h"
23 
24 #include "NativeThreadLinux.h"
25 #include "lldb/Host/common/NativeProcessProtocol.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   friend Error NativeProcessProtocol::Launch(
41       ProcessLaunchInfo &launch_info, NativeDelegate &native_delegate,
42       MainLoop &mainloop, NativeProcessProtocolSP &process_sp);
43 
44   friend Error NativeProcessProtocol::Attach(
45       lldb::pid_t pid, NativeProcessProtocol::NativeDelegate &native_delegate,
46       MainLoop &mainloop, NativeProcessProtocolSP &process_sp);
47 
48 public:
49   // ---------------------------------------------------------------------
50   // NativeProcessProtocol Interface
51   // ---------------------------------------------------------------------
52   Error Resume(const ResumeActionList &resume_actions) override;
53 
54   Error Halt() override;
55 
56   Error Detach() override;
57 
58   Error Signal(int signo) override;
59 
60   Error Interrupt() override;
61 
62   Error Kill() override;
63 
64   Error GetMemoryRegionInfo(lldb::addr_t load_addr,
65                             MemoryRegionInfo &range_info) override;
66 
67   Error ReadMemory(lldb::addr_t addr, void *buf, size_t size,
68                    size_t &bytes_read) override;
69 
70   Error ReadMemoryWithoutTrap(lldb::addr_t addr, void *buf, size_t size,
71                               size_t &bytes_read) override;
72 
73   Error WriteMemory(lldb::addr_t addr, const void *buf, size_t size,
74                     size_t &bytes_written) override;
75 
76   Error AllocateMemory(size_t size, uint32_t permissions,
77                        lldb::addr_t &addr) override;
78 
79   Error DeallocateMemory(lldb::addr_t addr) override;
80 
81   lldb::addr_t GetSharedLibraryInfoAddress() override;
82 
83   size_t UpdateThreads() override;
84 
85   bool GetArchitecture(ArchSpec &arch) const override;
86 
87   Error SetBreakpoint(lldb::addr_t addr, uint32_t size, bool hardware) override;
88 
89   Error RemoveBreakpoint(lldb::addr_t addr, bool hardware = false) override;
90 
91   void DoStopIDBumped(uint32_t newBumpId) override;
92 
93   Error GetLoadedModuleFileSpec(const char *module_path,
94                                 FileSpec &file_spec) override;
95 
96   Error GetFileLoadAddress(const llvm::StringRef &file_name,
97                            lldb::addr_t &load_addr) override;
98 
99   NativeThreadLinuxSP GetThreadByID(lldb::tid_t id);
100 
101   // ---------------------------------------------------------------------
102   // Interface used by NativeRegisterContext-derived classes.
103   // ---------------------------------------------------------------------
104   static Error PtraceWrapper(int req, lldb::pid_t pid, void *addr = nullptr,
105                              void *data = nullptr, size_t data_size = 0,
106                              long *result = nullptr);
107 
108   bool SupportHardwareSingleStepping() const;
109 
110 protected:
111   // ---------------------------------------------------------------------
112   // NativeProcessProtocol protected interface
113   // ---------------------------------------------------------------------
114   Error
115   GetSoftwareBreakpointTrapOpcode(size_t trap_opcode_size_hint,
116                                   size_t &actual_opcode_size,
117                                   const uint8_t *&trap_opcode_bytes) override;
118 
119 private:
120   MainLoop::SignalHandleUP m_sigchld_handle;
121   ArchSpec m_arch;
122 
123   LazyBool m_supports_mem_region;
124   std::vector<std::pair<MemoryRegionInfo, FileSpec>> m_mem_region_cache;
125 
126   lldb::tid_t m_pending_notification_tid;
127 
128   // List of thread ids stepping with a breakpoint with the address of
129   // the relevan breakpoint
130   std::map<lldb::tid_t, lldb::addr_t> m_threads_stepping_with_breakpoint;
131 
132   // ---------------------------------------------------------------------
133   // Private Instance Methods
134   // ---------------------------------------------------------------------
135   NativeProcessLinux();
136 
137   Error LaunchInferior(MainLoop &mainloop, ProcessLaunchInfo &launch_info);
138 
139   /// Attaches to an existing process.  Forms the
140   /// implementation of Process::DoAttach
141   void AttachToInferior(MainLoop &mainloop, lldb::pid_t pid, Error &error);
142 
143   ::pid_t Attach(lldb::pid_t pid, Error &error);
144 
145   static Error SetDefaultPtraceOpts(const lldb::pid_t);
146 
147   static void *MonitorThread(void *baton);
148 
149   void MonitorCallback(lldb::pid_t pid, bool exited, int signal, int status);
150 
151   void WaitForNewThread(::pid_t tid);
152 
153   void MonitorSIGTRAP(const siginfo_t &info, NativeThreadLinux &thread);
154 
155   void MonitorTrace(NativeThreadLinux &thread);
156 
157   void MonitorBreakpoint(NativeThreadLinux &thread);
158 
159   void MonitorWatchpoint(NativeThreadLinux &thread, uint32_t wp_index);
160 
161   void MonitorSignal(const siginfo_t &info, NativeThreadLinux &thread,
162                      bool exited);
163 
164   Error SetupSoftwareSingleStepping(NativeThreadLinux &thread);
165 
166 #if 0
167         static ::ProcessMessage::CrashReason
168         GetCrashReasonForSIGSEGV(const siginfo_t *info);
169 
170         static ::ProcessMessage::CrashReason
171         GetCrashReasonForSIGILL(const siginfo_t *info);
172 
173         static ::ProcessMessage::CrashReason
174         GetCrashReasonForSIGFPE(const siginfo_t *info);
175 
176         static ::ProcessMessage::CrashReason
177         GetCrashReasonForSIGBUS(const siginfo_t *info);
178 #endif
179 
180   bool HasThreadNoLock(lldb::tid_t thread_id);
181 
182   bool StopTrackingThread(lldb::tid_t thread_id);
183 
184   NativeThreadLinuxSP AddThread(lldb::tid_t thread_id);
185 
186   Error GetSoftwareBreakpointPCOffset(uint32_t &actual_opcode_size);
187 
188   Error FixupBreakpointPCAsNeeded(NativeThreadLinux &thread);
189 
190   /// Writes a siginfo_t structure corresponding to the given thread ID to the
191   /// memory region pointed to by @p siginfo.
192   Error GetSignalInfo(lldb::tid_t tid, void *siginfo);
193 
194   /// Writes the raw event message code (vis-a-vis PTRACE_GETEVENTMSG)
195   /// corresponding to the given thread ID to the memory pointed to by @p
196   /// message.
197   Error GetEventMessage(lldb::tid_t tid, unsigned long *message);
198 
199   void NotifyThreadDeath(lldb::tid_t tid);
200 
201   Error Detach(lldb::tid_t tid);
202 
203   // This method is requests a stop on all threads which are still running. It
204   // sets up a
205   // deferred delegate notification, which will fire once threads report as
206   // stopped. The
207   // triggerring_tid will be set as the current thread (main stop reason).
208   void StopRunningThreads(lldb::tid_t triggering_tid);
209 
210   // Notify the delegate if all threads have stopped.
211   void SignalIfAllThreadsStopped();
212 
213   // Resume the given thread, optionally passing it the given signal. The type
214   // of resume
215   // operation (continue, single-step) depends on the state parameter.
216   Error ResumeThread(NativeThreadLinux &thread, lldb::StateType state,
217                      int signo);
218 
219   void ThreadWasCreated(NativeThreadLinux &thread);
220 
221   void SigchldHandler();
222 
223   Error PopulateMemoryRegionCache();
224 };
225 
226 } // namespace process_linux
227 } // namespace lldb_private
228 
229 #endif // #ifndef liblldb_NativeProcessLinux_H_
230