1af245d11STodd Fiala //===-- NativeProcessLinux.h ---------------------------------- -*- C++ -*-===//
2af245d11STodd Fiala //
3af245d11STodd Fiala //                     The LLVM Compiler Infrastructure
4af245d11STodd Fiala //
5af245d11STodd Fiala // This file is distributed under the University of Illinois Open Source
6af245d11STodd Fiala // License. See LICENSE.TXT for details.
7af245d11STodd Fiala //
8af245d11STodd Fiala //===----------------------------------------------------------------------===//
9af245d11STodd Fiala 
10af245d11STodd Fiala #ifndef liblldb_NativeProcessLinux_H_
11af245d11STodd Fiala #define liblldb_NativeProcessLinux_H_
12af245d11STodd Fiala 
13af245d11STodd Fiala // C++ Includes
14af245d11STodd Fiala #include <unordered_set>
15af245d11STodd Fiala 
16af245d11STodd Fiala // Other libraries and framework includes
17af245d11STodd Fiala #include "lldb/Core/ArchSpec.h"
18af245d11STodd Fiala #include "lldb/Host/Debug.h"
1939de3110SZachary Turner #include "lldb/Host/HostThread.h"
20b7f0f45fSPavel Labath #include "lldb/Host/linux/Support.h"
21af245d11STodd Fiala #include "lldb/Target/MemoryRegionInfo.h"
225713a05bSZachary Turner #include "lldb/Utility/FileSpec.h"
23b9c1b51eSKate Stone #include "lldb/lldb-types.h"
24af245d11STodd Fiala 
258c8ff7afSPavel Labath #include "NativeThreadLinux.h"
26*99e37695SRavitheja Addepally #include "ProcessorTrace.h"
27b9c1b51eSKate Stone #include "lldb/Host/common/NativeProcessProtocol.h"
28af245d11STodd Fiala 
29db264a6dSTamas Berghammer namespace lldb_private {
3097206d57SZachary Turner class Status;
31af245d11STodd Fiala class Scalar;
32af245d11STodd Fiala 
33db264a6dSTamas Berghammer namespace process_linux {
34af245d11STodd Fiala /// @class NativeProcessLinux
35af245d11STodd Fiala /// @brief Manages communication with the inferior (debugee) process.
36af245d11STodd Fiala ///
37af245d11STodd Fiala /// Upon construction, this class prepares and launches an inferior process for
38af245d11STodd Fiala /// debugging.
39af245d11STodd Fiala ///
40af245d11STodd Fiala /// Changes in the inferior process state are broadcasted.
41b9c1b51eSKate Stone class NativeProcessLinux : public NativeProcessProtocol {
4297206d57SZachary Turner   friend Status NativeProcessProtocol::Launch(
43b9c1b51eSKate Stone       ProcessLaunchInfo &launch_info, NativeDelegate &native_delegate,
44b9c1b51eSKate Stone       MainLoop &mainloop, NativeProcessProtocolSP &process_sp);
45d5b310f2SPavel Labath 
4697206d57SZachary Turner   friend Status NativeProcessProtocol::Attach(
47b9c1b51eSKate Stone       lldb::pid_t pid, NativeProcessProtocol::NativeDelegate &native_delegate,
48b9c1b51eSKate Stone       MainLoop &mainloop, NativeProcessProtocolSP &process_sp);
49d5b310f2SPavel Labath 
50c307c270SSean Callanan public:
51af245d11STodd Fiala   // ---------------------------------------------------------------------
52af245d11STodd Fiala   // NativeProcessProtocol Interface
53af245d11STodd Fiala   // ---------------------------------------------------------------------
5497206d57SZachary Turner   Status Resume(const ResumeActionList &resume_actions) override;
55af245d11STodd Fiala 
5697206d57SZachary Turner   Status Halt() override;
57af245d11STodd Fiala 
5897206d57SZachary Turner   Status Detach() override;
59af245d11STodd Fiala 
6097206d57SZachary Turner   Status Signal(int signo) override;
61af245d11STodd Fiala 
6297206d57SZachary Turner   Status Interrupt() override;
63e9547b80SChaoren Lin 
6497206d57SZachary Turner   Status Kill() override;
65af245d11STodd Fiala 
6697206d57SZachary Turner   Status GetMemoryRegionInfo(lldb::addr_t load_addr,
67b9c1b51eSKate Stone                              MemoryRegionInfo &range_info) override;
68af245d11STodd Fiala 
6997206d57SZachary Turner   Status ReadMemory(lldb::addr_t addr, void *buf, size_t size,
70b9c1b51eSKate Stone                     size_t &bytes_read) override;
71af245d11STodd Fiala 
7297206d57SZachary Turner   Status ReadMemoryWithoutTrap(lldb::addr_t addr, void *buf, size_t size,
73b9c1b51eSKate Stone                                size_t &bytes_read) override;
74af245d11STodd Fiala 
7597206d57SZachary Turner   Status WriteMemory(lldb::addr_t addr, const void *buf, size_t size,
76b9c1b51eSKate Stone                      size_t &bytes_written) override;
773eb4b458SChaoren Lin 
7897206d57SZachary Turner   Status AllocateMemory(size_t size, uint32_t permissions,
79b9c1b51eSKate Stone                         lldb::addr_t &addr) override;
80af245d11STodd Fiala 
8197206d57SZachary Turner   Status DeallocateMemory(lldb::addr_t addr) override;
82af245d11STodd Fiala 
83b9c1b51eSKate Stone   lldb::addr_t GetSharedLibraryInfoAddress() override;
84af245d11STodd Fiala 
85b9c1b51eSKate Stone   size_t UpdateThreads() override;
86af245d11STodd Fiala 
87b9c1b51eSKate Stone   bool GetArchitecture(ArchSpec &arch) const override;
88af245d11STodd Fiala 
8997206d57SZachary Turner   Status SetBreakpoint(lldb::addr_t addr, uint32_t size,
9097206d57SZachary Turner                        bool hardware) override;
91af245d11STodd Fiala 
9297206d57SZachary Turner   Status RemoveBreakpoint(lldb::addr_t addr, bool hardware = false) override;
93d5ffbad2SOmair Javaid 
94b9c1b51eSKate Stone   void DoStopIDBumped(uint32_t newBumpId) override;
95af245d11STodd Fiala 
9697206d57SZachary Turner   Status GetLoadedModuleFileSpec(const char *module_path,
97b9c1b51eSKate Stone                                  FileSpec &file_spec) override;
98068f8a7eSTamas Berghammer 
9997206d57SZachary Turner   Status GetFileLoadAddress(const llvm::StringRef &file_name,
100b9c1b51eSKate Stone                             lldb::addr_t &load_addr) override;
101783bfc8cSTamas Berghammer 
102b9c1b51eSKate Stone   NativeThreadLinuxSP GetThreadByID(lldb::tid_t id);
103f9077782SPavel Labath 
104b7f0f45fSPavel Labath   llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>>
105b7f0f45fSPavel Labath   GetAuxvData() const override {
106b7f0f45fSPavel Labath     return getProcFile(GetID(), "auxv");
107b7f0f45fSPavel Labath   }
108b7f0f45fSPavel Labath 
109*99e37695SRavitheja Addepally   lldb::user_id_t StartTrace(const TraceOptions &config,
110*99e37695SRavitheja Addepally                              Status &error) override;
111*99e37695SRavitheja Addepally 
112*99e37695SRavitheja Addepally   Status StopTrace(lldb::user_id_t traceid,
113*99e37695SRavitheja Addepally                    lldb::tid_t thread) override;
114*99e37695SRavitheja Addepally 
115*99e37695SRavitheja Addepally   Status GetData(lldb::user_id_t traceid, lldb::tid_t thread,
116*99e37695SRavitheja Addepally                  llvm::MutableArrayRef<uint8_t> &buffer,
117*99e37695SRavitheja Addepally                  size_t offset = 0) override;
118*99e37695SRavitheja Addepally 
119*99e37695SRavitheja Addepally   Status GetMetaData(lldb::user_id_t traceid, lldb::tid_t thread,
120*99e37695SRavitheja Addepally                      llvm::MutableArrayRef<uint8_t> &buffer,
121*99e37695SRavitheja Addepally                      size_t offset = 0) override;
122*99e37695SRavitheja Addepally 
123*99e37695SRavitheja Addepally   Status GetTraceConfig(lldb::user_id_t traceid, TraceOptions &config) override;
124*99e37695SRavitheja Addepally 
125af245d11STodd Fiala   // ---------------------------------------------------------------------
126af245d11STodd Fiala   // Interface used by NativeRegisterContext-derived classes.
127af245d11STodd Fiala   // ---------------------------------------------------------------------
12897206d57SZachary Turner   static Status PtraceWrapper(int req, lldb::pid_t pid, void *addr = nullptr,
129b9c1b51eSKate Stone                               void *data = nullptr, size_t data_size = 0,
1304a9babb2SPavel Labath                               long *result = nullptr);
1317cb18bf5STamas Berghammer 
132b9c1b51eSKate Stone   bool SupportHardwareSingleStepping() const;
133605b51b8SPavel Labath 
134af245d11STodd Fiala protected:
135af245d11STodd Fiala   // ---------------------------------------------------------------------
136af245d11STodd Fiala   // NativeProcessProtocol protected interface
137af245d11STodd Fiala   // ---------------------------------------------------------------------
13897206d57SZachary Turner   Status
139b9c1b51eSKate Stone   GetSoftwareBreakpointTrapOpcode(size_t trap_opcode_size_hint,
140b9c1b51eSKate Stone                                   size_t &actual_opcode_size,
141b9c1b51eSKate Stone                                   const uint8_t *&trap_opcode_bytes) override;
142af245d11STodd Fiala 
143af245d11STodd Fiala private:
14419cbe96aSPavel Labath   MainLoop::SignalHandleUP m_sigchld_handle;
145db264a6dSTamas Berghammer   ArchSpec m_arch;
146af245d11STodd Fiala 
147db264a6dSTamas Berghammer   LazyBool m_supports_mem_region;
148a6f5795aSTamas Berghammer   std::vector<std::pair<MemoryRegionInfo, FileSpec>> m_mem_region_cache;
149af245d11STodd Fiala 
1500e1d729bSPavel Labath   lldb::tid_t m_pending_notification_tid;
1510e1d729bSPavel Labath 
152d8c338d4STamas Berghammer   // List of thread ids stepping with a breakpoint with the address of
153d8c338d4STamas Berghammer   // the relevan breakpoint
154d8c338d4STamas Berghammer   std::map<lldb::tid_t, lldb::addr_t> m_threads_stepping_with_breakpoint;
155d8c338d4STamas Berghammer 
156af245d11STodd Fiala   // ---------------------------------------------------------------------
157af245d11STodd Fiala   // Private Instance Methods
158af245d11STodd Fiala   // ---------------------------------------------------------------------
159af245d11STodd Fiala   NativeProcessLinux();
160af245d11STodd Fiala 
16197206d57SZachary Turner   Status LaunchInferior(MainLoop &mainloop, ProcessLaunchInfo &launch_info);
162af245d11STodd Fiala 
163af245d11STodd Fiala   /// Attaches to an existing process.  Forms the
1640cbf0b13STamas Berghammer   /// implementation of Process::DoAttach
16597206d57SZachary Turner   void AttachToInferior(MainLoop &mainloop, lldb::pid_t pid, Status &error);
1661107b5a5SPavel Labath 
16797206d57SZachary Turner   ::pid_t Attach(lldb::pid_t pid, Status &error);
168af245d11STodd Fiala 
16997206d57SZachary Turner   static Status SetDefaultPtraceOpts(const lldb::pid_t);
170af245d11STodd Fiala 
171b9c1b51eSKate Stone   static void *MonitorThread(void *baton);
1721107b5a5SPavel Labath 
1733508fc8cSPavel Labath   void MonitorCallback(lldb::pid_t pid, bool exited, WaitStatus status);
174af245d11STodd Fiala 
175b9c1b51eSKate Stone   void WaitForNewThread(::pid_t tid);
176426bdf88SPavel Labath 
177b9c1b51eSKate Stone   void MonitorSIGTRAP(const siginfo_t &info, NativeThreadLinux &thread);
178af245d11STodd Fiala 
179b9c1b51eSKate Stone   void MonitorTrace(NativeThreadLinux &thread);
180c16f5dcaSChaoren Lin 
181b9c1b51eSKate Stone   void MonitorBreakpoint(NativeThreadLinux &thread);
182c16f5dcaSChaoren Lin 
183b9c1b51eSKate Stone   void MonitorWatchpoint(NativeThreadLinux &thread, uint32_t wp_index);
184c16f5dcaSChaoren Lin 
185b9c1b51eSKate Stone   void MonitorSignal(const siginfo_t &info, NativeThreadLinux &thread,
186b9c1b51eSKate Stone                      bool exited);
187af245d11STodd Fiala 
18897206d57SZachary Turner   Status SetupSoftwareSingleStepping(NativeThreadLinux &thread);
189e7708688STamas Berghammer 
190af245d11STodd Fiala #if 0
191af245d11STodd Fiala         static ::ProcessMessage::CrashReason
192af245d11STodd Fiala         GetCrashReasonForSIGSEGV(const siginfo_t *info);
193af245d11STodd Fiala 
194af245d11STodd Fiala         static ::ProcessMessage::CrashReason
195af245d11STodd Fiala         GetCrashReasonForSIGILL(const siginfo_t *info);
196af245d11STodd Fiala 
197af245d11STodd Fiala         static ::ProcessMessage::CrashReason
198af245d11STodd Fiala         GetCrashReasonForSIGFPE(const siginfo_t *info);
199af245d11STodd Fiala 
200af245d11STodd Fiala         static ::ProcessMessage::CrashReason
201af245d11STodd Fiala         GetCrashReasonForSIGBUS(const siginfo_t *info);
202af245d11STodd Fiala #endif
203af245d11STodd Fiala 
204b9c1b51eSKate Stone   bool HasThreadNoLock(lldb::tid_t thread_id);
205af245d11STodd Fiala 
206b9c1b51eSKate Stone   bool StopTrackingThread(lldb::tid_t thread_id);
207af245d11STodd Fiala 
208b9c1b51eSKate Stone   NativeThreadLinuxSP AddThread(lldb::tid_t thread_id);
209af245d11STodd Fiala 
21097206d57SZachary Turner   Status GetSoftwareBreakpointPCOffset(uint32_t &actual_opcode_size);
211af245d11STodd Fiala 
21297206d57SZachary Turner   Status FixupBreakpointPCAsNeeded(NativeThreadLinux &thread);
213af245d11STodd Fiala 
214af245d11STodd Fiala   /// Writes a siginfo_t structure corresponding to the given thread ID to the
215af245d11STodd Fiala   /// memory region pointed to by @p siginfo.
21697206d57SZachary Turner   Status GetSignalInfo(lldb::tid_t tid, void *siginfo);
217af245d11STodd Fiala 
218af245d11STodd Fiala   /// Writes the raw event message code (vis-a-vis PTRACE_GETEVENTMSG)
219af245d11STodd Fiala   /// corresponding to the given thread ID to the memory pointed to by @p
220af245d11STodd Fiala   /// message.
22197206d57SZachary Turner   Status GetEventMessage(lldb::tid_t tid, unsigned long *message);
222af245d11STodd Fiala 
223b9c1b51eSKate Stone   void NotifyThreadDeath(lldb::tid_t tid);
224fa03ad2eSChaoren Lin 
22597206d57SZachary Turner   Status Detach(lldb::tid_t tid);
22686fd8e45SChaoren Lin 
227b9c1b51eSKate Stone   // This method is requests a stop on all threads which are still running. It
228b9c1b51eSKate Stone   // sets up a
229b9c1b51eSKate Stone   // deferred delegate notification, which will fire once threads report as
230b9c1b51eSKate Stone   // stopped. The
2311dbc6c9cSPavel Labath   // triggerring_tid will be set as the current thread (main stop reason).
232b9c1b51eSKate Stone   void StopRunningThreads(lldb::tid_t triggering_tid);
233c076559aSPavel Labath 
2349eb1ecb9SPavel Labath   // Notify the delegate if all threads have stopped.
2359eb1ecb9SPavel Labath   void SignalIfAllThreadsStopped();
236c076559aSPavel Labath 
237b9c1b51eSKate Stone   // Resume the given thread, optionally passing it the given signal. The type
238b9c1b51eSKate Stone   // of resume
2390e1d729bSPavel Labath   // operation (continue, single-step) depends on the state parameter.
24097206d57SZachary Turner   Status ResumeThread(NativeThreadLinux &thread, lldb::StateType state,
241b9c1b51eSKate Stone                       int signo);
242c076559aSPavel Labath 
243b9c1b51eSKate Stone   void ThreadWasCreated(NativeThreadLinux &thread);
244c076559aSPavel Labath 
245b9c1b51eSKate Stone   void SigchldHandler();
246a6f5795aSTamas Berghammer 
24797206d57SZachary Turner   Status PopulateMemoryRegionCache();
248*99e37695SRavitheja Addepally 
249*99e37695SRavitheja Addepally   lldb::user_id_t StartTraceGroup(const TraceOptions &config,
250*99e37695SRavitheja Addepally                                          Status &error);
251*99e37695SRavitheja Addepally 
252*99e37695SRavitheja Addepally   // This function is intended to be used to stop tracing
253*99e37695SRavitheja Addepally   // on a thread that exited.
254*99e37695SRavitheja Addepally   Status StopTracingForThread(lldb::tid_t thread);
255*99e37695SRavitheja Addepally 
256*99e37695SRavitheja Addepally   // The below function as the name suggests, looks up a ProcessorTrace
257*99e37695SRavitheja Addepally   // instance from the m_processor_trace_monitor map. In the case of
258*99e37695SRavitheja Addepally   // process tracing where the traceid passed would map to the complete
259*99e37695SRavitheja Addepally   // process, it is mandatory to provide a threadid to obtain a trace
260*99e37695SRavitheja Addepally   // instance (since ProcessorTrace is tied to a thread). In the other
261*99e37695SRavitheja Addepally   // scenario that an individual thread is being traced, just the traceid
262*99e37695SRavitheja Addepally   // is sufficient to obtain the actual ProcessorTrace instance.
263*99e37695SRavitheja Addepally   llvm::Expected<ProcessorTraceMonitor &>
264*99e37695SRavitheja Addepally   LookupProcessorTraceInstance(lldb::user_id_t traceid, lldb::tid_t thread);
265*99e37695SRavitheja Addepally 
266*99e37695SRavitheja Addepally   // Stops tracing on individual threads being traced. Not intended
267*99e37695SRavitheja Addepally   // to be used to stop tracing on complete process.
268*99e37695SRavitheja Addepally   Status StopProcessorTracingOnThread(lldb::user_id_t traceid,
269*99e37695SRavitheja Addepally                                       lldb::tid_t thread);
270*99e37695SRavitheja Addepally 
271*99e37695SRavitheja Addepally   // Intended to stop tracing on complete process.
272*99e37695SRavitheja Addepally   // Should not be used for stopping trace on
273*99e37695SRavitheja Addepally   // individual threads.
274*99e37695SRavitheja Addepally   void StopProcessorTracingOnProcess();
275*99e37695SRavitheja Addepally 
276*99e37695SRavitheja Addepally   llvm::DenseMap<lldb::tid_t, ProcessorTraceMonitorUP>
277*99e37695SRavitheja Addepally       m_processor_trace_monitor;
278*99e37695SRavitheja Addepally 
279*99e37695SRavitheja Addepally   // Set for tracking threads being traced under
280*99e37695SRavitheja Addepally   // same process user id.
281*99e37695SRavitheja Addepally   llvm::DenseSet<lldb::tid_t> m_pt_traced_thread_group;
282*99e37695SRavitheja Addepally 
283*99e37695SRavitheja Addepally   lldb::user_id_t m_pt_proces_trace_id;
284*99e37695SRavitheja Addepally   TraceOptions m_pt_process_trace_config;
285af245d11STodd Fiala };
286db264a6dSTamas Berghammer 
287db264a6dSTamas Berghammer } // namespace process_linux
288db264a6dSTamas Berghammer } // namespace lldb_private
289af245d11STodd Fiala 
290af245d11STodd Fiala #endif // #ifndef liblldb_NativeProcessLinux_H_
291