1af245d11STodd Fiala //===-- NativeProcessLinux.h ---------------------------------- -*- C++ -*-===//
2af245d11STodd Fiala //
32946cd70SChandler Carruth // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
42946cd70SChandler Carruth // See https://llvm.org/LICENSE.txt for license information.
52946cd70SChandler Carruth // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6af245d11STodd Fiala //
7af245d11STodd Fiala //===----------------------------------------------------------------------===//
8af245d11STodd Fiala 
9af245d11STodd Fiala #ifndef liblldb_NativeProcessLinux_H_
10af245d11STodd Fiala #define liblldb_NativeProcessLinux_H_
11af245d11STodd Fiala 
12b6dbe9a9SPavel Labath #include <csignal>
13af245d11STodd Fiala #include <unordered_set>
14af245d11STodd Fiala 
15af245d11STodd Fiala #include "lldb/Host/Debug.h"
1639de3110SZachary Turner #include "lldb/Host/HostThread.h"
17b7f0f45fSPavel Labath #include "lldb/Host/linux/Support.h"
18af245d11STodd Fiala #include "lldb/Target/MemoryRegionInfo.h"
195f19b907SPavel Labath #include "lldb/Utility/ArchSpec.h"
205713a05bSZachary Turner #include "lldb/Utility/FileSpec.h"
21b9c1b51eSKate Stone #include "lldb/lldb-types.h"
22af245d11STodd Fiala 
230b697561SWalter Erquinigo #include "IntelPTManager.h"
248c8ff7afSPavel Labath #include "NativeThreadLinux.h"
25f4335b8eSAntonio Afonso #include "Plugins/Process/POSIX/NativeProcessELF.h"
268244fc50SMichał Górny #include "Plugins/Process/Utility/NativeProcessSoftwareSingleStep.h"
27af245d11STodd Fiala 
28db264a6dSTamas Berghammer namespace lldb_private {
2997206d57SZachary Turner class Status;
30af245d11STodd Fiala class Scalar;
31af245d11STodd Fiala 
32db264a6dSTamas Berghammer namespace process_linux {
33f05b42e9SAdrian Prantl /// \class NativeProcessLinux
34d8f460e8SAdrian Prantl /// Manages communication with the inferior (debugee) process.
35af245d11STodd Fiala ///
36d8f460e8SAdrian Prantl /// Upon construction, this class prepares and launches an inferior process
37d8f460e8SAdrian Prantl /// for debugging.
38af245d11STodd Fiala ///
39af245d11STodd Fiala /// Changes in the inferior process state are broadcasted.
408244fc50SMichał Górny class NativeProcessLinux : public NativeProcessELF,
418244fc50SMichał Górny                            private NativeProcessSoftwareSingleStep {
42c307c270SSean Callanan public:
4396e600fcSPavel Labath   class Factory : public NativeProcessProtocol::Factory {
4496e600fcSPavel Labath   public:
4582abefa4SPavel Labath     llvm::Expected<std::unique_ptr<NativeProcessProtocol>>
4696e600fcSPavel Labath     Launch(ProcessLaunchInfo &launch_info, NativeDelegate &native_delegate,
4796e600fcSPavel Labath            MainLoop &mainloop) const override;
4896e600fcSPavel Labath 
4982abefa4SPavel Labath     llvm::Expected<std::unique_ptr<NativeProcessProtocol>>
5096e600fcSPavel Labath     Attach(lldb::pid_t pid, NativeDelegate &native_delegate,
5196e600fcSPavel Labath            MainLoop &mainloop) const override;
52fd0af0cfSMichał Górny 
53fd0af0cfSMichał Górny     Extension GetSupportedExtensions() const override;
5496e600fcSPavel Labath   };
5596e600fcSPavel Labath 
56af245d11STodd Fiala   // NativeProcessProtocol Interface
5797206d57SZachary Turner   Status Resume(const ResumeActionList &resume_actions) override;
58af245d11STodd Fiala 
5997206d57SZachary Turner   Status Halt() override;
60af245d11STodd Fiala 
6197206d57SZachary Turner   Status Detach() override;
62af245d11STodd Fiala 
6397206d57SZachary Turner   Status Signal(int signo) override;
64af245d11STodd Fiala 
6597206d57SZachary Turner   Status Interrupt() override;
66e9547b80SChaoren Lin 
6797206d57SZachary Turner   Status Kill() override;
68af245d11STodd Fiala 
6997206d57SZachary Turner   Status GetMemoryRegionInfo(lldb::addr_t load_addr,
70b9c1b51eSKate Stone                              MemoryRegionInfo &range_info) override;
71af245d11STodd Fiala 
7297206d57SZachary Turner   Status ReadMemory(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 
782c4226f8SPavel Labath   llvm::Expected<lldb::addr_t> AllocateMemory(size_t size,
792c4226f8SPavel Labath                                               uint32_t permissions) override;
80af245d11STodd Fiala 
812c4226f8SPavel Labath   llvm::Error DeallocateMemory(lldb::addr_t addr) override;
82af245d11STodd Fiala 
83da2e614fSDavid Spickett   Status ReadMemoryTags(int32_t type, lldb::addr_t addr, size_t len,
84da2e614fSDavid Spickett                         std::vector<uint8_t> &tags) override;
85da2e614fSDavid Spickett 
867d27230dSDavid Spickett   Status WriteMemoryTags(int32_t type, lldb::addr_t addr, size_t len,
877d27230dSDavid Spickett                          const std::vector<uint8_t> &tags) override;
887d27230dSDavid Spickett 
89b9c1b51eSKate Stone   size_t UpdateThreads() override;
90af245d11STodd Fiala 
91578a4258SPavel Labath   const ArchSpec &GetArchitecture() const override { return m_arch; }
92af245d11STodd Fiala 
9397206d57SZachary Turner   Status SetBreakpoint(lldb::addr_t addr, uint32_t size,
9497206d57SZachary Turner                        bool hardware) override;
95af245d11STodd Fiala 
9697206d57SZachary Turner   Status RemoveBreakpoint(lldb::addr_t addr, bool hardware = false) override;
97d5ffbad2SOmair Javaid 
98b9c1b51eSKate Stone   void DoStopIDBumped(uint32_t newBumpId) override;
99af245d11STodd Fiala 
10097206d57SZachary Turner   Status GetLoadedModuleFileSpec(const char *module_path,
101b9c1b51eSKate Stone                                  FileSpec &file_spec) override;
102068f8a7eSTamas Berghammer 
10397206d57SZachary Turner   Status GetFileLoadAddress(const llvm::StringRef &file_name,
104b9c1b51eSKate Stone                             lldb::addr_t &load_addr) override;
105783bfc8cSTamas Berghammer 
106a5be48b3SPavel Labath   NativeThreadLinux *GetThreadByID(lldb::tid_t id);
1072c4226f8SPavel Labath   NativeThreadLinux *GetCurrentThread();
108f9077782SPavel Labath 
109b7f0f45fSPavel Labath   llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>>
110b7f0f45fSPavel Labath   GetAuxvData() const override {
111b7f0f45fSPavel Labath     return getProcFile(GetID(), "auxv");
112b7f0f45fSPavel Labath   }
113b7f0f45fSPavel Labath 
1140b697561SWalter Erquinigo   /// Tracing
1150b697561SWalter Erquinigo   /// These methods implement the jLLDBTrace packets
1160b697561SWalter Erquinigo   /// \{
1170b697561SWalter Erquinigo   llvm::Error TraceStart(llvm::StringRef json_request,
1180b697561SWalter Erquinigo                          llvm::StringRef type) override;
11999e37695SRavitheja Addepally 
1200b697561SWalter Erquinigo   llvm::Error TraceStop(const TraceStopRequest &request) override;
12199e37695SRavitheja Addepally 
1220b697561SWalter Erquinigo   llvm::Expected<llvm::json::Value>
1230b697561SWalter Erquinigo   TraceGetState(llvm::StringRef type) override;
12499e37695SRavitheja Addepally 
1250b697561SWalter Erquinigo   llvm::Expected<std::vector<uint8_t>>
1260b697561SWalter Erquinigo   TraceGetBinaryData(const TraceGetBinaryDataRequest &request) override;
12799e37695SRavitheja Addepally 
1280b697561SWalter Erquinigo   llvm::Expected<TraceSupportedResponse> TraceSupported() override;
1290b697561SWalter Erquinigo   /// }
13021555fffSWalter Erquinigo 
131af245d11STodd Fiala   // Interface used by NativeRegisterContext-derived classes.
13297206d57SZachary Turner   static Status PtraceWrapper(int req, lldb::pid_t pid, void *addr = nullptr,
133b9c1b51eSKate Stone                               void *data = nullptr, size_t data_size = 0,
1344a9babb2SPavel Labath                               long *result = nullptr);
1357cb18bf5STamas Berghammer 
136b9c1b51eSKate Stone   bool SupportHardwareSingleStepping() const;
137605b51b8SPavel Labath 
138af245d11STodd Fiala protected:
139f8b825f6SPavel Labath   llvm::Expected<llvm::ArrayRef<uint8_t>>
140f8b825f6SPavel Labath   GetSoftwareBreakpointTrapOpcode(size_t size_hint) override;
141af245d11STodd Fiala 
1422c4226f8SPavel Labath   llvm::Expected<uint64_t> Syscall(llvm::ArrayRef<uint64_t> args);
1432c4226f8SPavel Labath 
144af245d11STodd Fiala private:
14519cbe96aSPavel Labath   MainLoop::SignalHandleUP m_sigchld_handle;
146db264a6dSTamas Berghammer   ArchSpec m_arch;
147fd0af0cfSMichał Górny   MainLoop& m_main_loop;
148af245d11STodd Fiala 
14996e600fcSPavel Labath   LazyBool m_supports_mem_region = eLazyBoolCalculate;
150a6f5795aSTamas Berghammer   std::vector<std::pair<MemoryRegionInfo, FileSpec>> m_mem_region_cache;
151af245d11STodd Fiala 
15296e600fcSPavel Labath   lldb::tid_t m_pending_notification_tid = LLDB_INVALID_THREAD_ID;
1530e1d729bSPavel Labath 
1542c4226f8SPavel Labath   /// Inferior memory (allocated by us) and its size.
1552c4226f8SPavel Labath   llvm::DenseMap<lldb::addr_t, lldb::addr_t> m_allocated_memory;
1562c4226f8SPavel Labath 
157af245d11STodd Fiala   // Private Instance Methods
15896e600fcSPavel Labath   NativeProcessLinux(::pid_t pid, int terminal_fd, NativeDelegate &delegate,
15982abefa4SPavel Labath                      const ArchSpec &arch, MainLoop &mainloop,
16082abefa4SPavel Labath                      llvm::ArrayRef<::pid_t> tids);
161af245d11STodd Fiala 
16296e600fcSPavel Labath   // Returns a list of process threads that we have attached to.
16396e600fcSPavel Labath   static llvm::Expected<std::vector<::pid_t>> Attach(::pid_t pid);
164af245d11STodd Fiala 
16597206d57SZachary Turner   static Status SetDefaultPtraceOpts(const lldb::pid_t);
166af245d11STodd Fiala 
167*ca271f4eSPavel Labath   void MonitorCallback(NativeThreadLinux &thread, WaitStatus status);
168af245d11STodd Fiala 
169c8d18cbaSMichał Górny   void WaitForCloneNotification(::pid_t pid);
170426bdf88SPavel Labath 
171b9c1b51eSKate Stone   void MonitorSIGTRAP(const siginfo_t &info, NativeThreadLinux &thread);
172af245d11STodd Fiala 
173b9c1b51eSKate Stone   void MonitorTrace(NativeThreadLinux &thread);
174c16f5dcaSChaoren Lin 
175b9c1b51eSKate Stone   void MonitorBreakpoint(NativeThreadLinux &thread);
176c16f5dcaSChaoren Lin 
177b9c1b51eSKate Stone   void MonitorWatchpoint(NativeThreadLinux &thread, uint32_t wp_index);
178c16f5dcaSChaoren Lin 
179fdd741ddSPavel Labath   void MonitorSignal(const siginfo_t &info, NativeThreadLinux &thread);
180af245d11STodd Fiala 
181b9c1b51eSKate Stone   bool HasThreadNoLock(lldb::tid_t thread_id);
182af245d11STodd Fiala 
183*ca271f4eSPavel Labath   void StopTrackingThread(NativeThreadLinux &thread);
184af245d11STodd Fiala 
1850b697561SWalter Erquinigo   /// Create a new thread.
1860b697561SWalter Erquinigo   ///
1870b697561SWalter Erquinigo   /// If process tracing is enabled and the thread can't be traced, then the
1880b697561SWalter Erquinigo   /// thread is left stopped with a \a eStopReasonProcessorTrace status, and
1890b697561SWalter Erquinigo   /// then the process is stopped.
1900b697561SWalter Erquinigo   ///
1910b697561SWalter Erquinigo   /// \param[in] resume
1920b697561SWalter Erquinigo   ///     If a tracing error didn't happen, then resume the thread after
1930b697561SWalter Erquinigo   ///     creation if \b true, or leave it stopped with SIGSTOP if \b false.
1940b697561SWalter Erquinigo   NativeThreadLinux &AddThread(lldb::tid_t thread_id, bool resume);
1950b697561SWalter Erquinigo 
1960b697561SWalter Erquinigo   /// Start tracing a new thread if process tracing is enabled.
1970b697561SWalter Erquinigo   ///
1980b697561SWalter Erquinigo   /// Trace mechanisms should modify this method to provide automatic tracing
1990b697561SWalter Erquinigo   /// for new threads.
2000b697561SWalter Erquinigo   Status NotifyTracersOfNewThread(lldb::tid_t tid);
2010b697561SWalter Erquinigo 
2020b697561SWalter Erquinigo   /// Stop tracing threads upon a destroy event.
2030b697561SWalter Erquinigo   ///
2040b697561SWalter Erquinigo   /// Trace mechanisms should modify this method to provide automatic trace
2050b697561SWalter Erquinigo   /// stopping for threads being destroyed.
2060b697561SWalter Erquinigo   Status NotifyTracersOfThreadDestroyed(lldb::tid_t tid);
207af245d11STodd Fiala 
208af245d11STodd Fiala   /// Writes a siginfo_t structure corresponding to the given thread ID to the
209f05b42e9SAdrian Prantl   /// memory region pointed to by \p siginfo.
21097206d57SZachary Turner   Status GetSignalInfo(lldb::tid_t tid, void *siginfo);
211af245d11STodd Fiala 
212af245d11STodd Fiala   /// Writes the raw event message code (vis-a-vis PTRACE_GETEVENTMSG)
213af245d11STodd Fiala   /// corresponding to the given thread ID to the memory pointed to by @p
214af245d11STodd Fiala   /// message.
21597206d57SZachary Turner   Status GetEventMessage(lldb::tid_t tid, unsigned long *message);
216af245d11STodd Fiala 
217b9c1b51eSKate Stone   void NotifyThreadDeath(lldb::tid_t tid);
218fa03ad2eSChaoren Lin 
21997206d57SZachary Turner   Status Detach(lldb::tid_t tid);
22086fd8e45SChaoren Lin 
221b9c1b51eSKate Stone   // This method is requests a stop on all threads which are still running. It
222b9c1b51eSKate Stone   // sets up a
223b9c1b51eSKate Stone   // deferred delegate notification, which will fire once threads report as
224b9c1b51eSKate Stone   // stopped. The
2251dbc6c9cSPavel Labath   // triggerring_tid will be set as the current thread (main stop reason).
226b9c1b51eSKate Stone   void StopRunningThreads(lldb::tid_t triggering_tid);
227c076559aSPavel Labath 
2289eb1ecb9SPavel Labath   // Notify the delegate if all threads have stopped.
2299eb1ecb9SPavel Labath   void SignalIfAllThreadsStopped();
230c076559aSPavel Labath 
231b9c1b51eSKate Stone   // Resume the given thread, optionally passing it the given signal. The type
232b9c1b51eSKate Stone   // of resume
2330e1d729bSPavel Labath   // operation (continue, single-step) depends on the state parameter.
23497206d57SZachary Turner   Status ResumeThread(NativeThreadLinux &thread, lldb::StateType state,
235b9c1b51eSKate Stone                       int signo);
236c076559aSPavel Labath 
237b9c1b51eSKate Stone   void ThreadWasCreated(NativeThreadLinux &thread);
238c076559aSPavel Labath 
239b9c1b51eSKate Stone   void SigchldHandler();
240a6f5795aSTamas Berghammer 
24197206d57SZachary Turner   Status PopulateMemoryRegionCache();
24299e37695SRavitheja Addepally 
2430b697561SWalter Erquinigo   /// Manages Intel PT process and thread traces.
2440b697561SWalter Erquinigo   IntelPTManager m_intel_pt_manager;
245c8d18cbaSMichał Górny 
246*ca271f4eSPavel Labath   // Handle a clone()-like event.
247*ca271f4eSPavel Labath   bool MonitorClone(NativeThreadLinux &parent, lldb::pid_t child_pid,
248*ca271f4eSPavel Labath                     int event);
249af245d11STodd Fiala };
250db264a6dSTamas Berghammer 
251db264a6dSTamas Berghammer } // namespace process_linux
252db264a6dSTamas Berghammer } // namespace lldb_private
253af245d11STodd Fiala 
254af245d11STodd Fiala #endif // #ifndef liblldb_NativeProcessLinux_H_
255