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 
2322077627SJakob Johnson #include "IntelPTCollector.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 
GetArchitecture()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>>
GetAuxvData()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 
1381e74e5e9SMichał Górny   /// Writes a siginfo_t structure corresponding to the given thread ID to the
1391e74e5e9SMichał Górny   /// memory region pointed to by \p siginfo.
1401e74e5e9SMichał Górny   Status GetSignalInfo(lldb::tid_t tid, void *siginfo) const;
1411e74e5e9SMichał Górny 
142af245d11STodd Fiala protected:
143f8b825f6SPavel Labath   llvm::Expected<llvm::ArrayRef<uint8_t>>
144f8b825f6SPavel Labath   GetSoftwareBreakpointTrapOpcode(size_t size_hint) override;
145af245d11STodd Fiala 
1462c4226f8SPavel Labath   llvm::Expected<uint64_t> Syscall(llvm::ArrayRef<uint64_t> args);
1472c4226f8SPavel Labath 
148af245d11STodd Fiala private:
14919cbe96aSPavel Labath   MainLoop::SignalHandleUP m_sigchld_handle;
150db264a6dSTamas Berghammer   ArchSpec m_arch;
151fd0af0cfSMichał Górny   MainLoop& m_main_loop;
152af245d11STodd Fiala 
15396e600fcSPavel Labath   LazyBool m_supports_mem_region = eLazyBoolCalculate;
154a6f5795aSTamas Berghammer   std::vector<std::pair<MemoryRegionInfo, FileSpec>> m_mem_region_cache;
155af245d11STodd Fiala 
15696e600fcSPavel Labath   lldb::tid_t m_pending_notification_tid = LLDB_INVALID_THREAD_ID;
1570e1d729bSPavel Labath 
1582c4226f8SPavel Labath   /// Inferior memory (allocated by us) and its size.
1592c4226f8SPavel Labath   llvm::DenseMap<lldb::addr_t, lldb::addr_t> m_allocated_memory;
1602c4226f8SPavel Labath 
161af245d11STodd Fiala   // Private Instance Methods
16296e600fcSPavel Labath   NativeProcessLinux(::pid_t pid, int terminal_fd, NativeDelegate &delegate,
16382abefa4SPavel Labath                      const ArchSpec &arch, MainLoop &mainloop,
16482abefa4SPavel Labath                      llvm::ArrayRef<::pid_t> tids);
165af245d11STodd Fiala 
16696e600fcSPavel Labath   // Returns a list of process threads that we have attached to.
16796e600fcSPavel Labath   static llvm::Expected<std::vector<::pid_t>> Attach(::pid_t pid);
168af245d11STodd Fiala 
16997206d57SZachary Turner   static Status SetDefaultPtraceOpts(const lldb::pid_t);
170af245d11STodd Fiala 
171ca271f4eSPavel Labath   void MonitorCallback(NativeThreadLinux &thread, WaitStatus status);
172af245d11STodd Fiala 
173c8d18cbaSMichał Górny   void WaitForCloneNotification(::pid_t pid);
174426bdf88SPavel Labath 
175b9c1b51eSKate Stone   void MonitorSIGTRAP(const siginfo_t &info, NativeThreadLinux &thread);
176af245d11STodd Fiala 
177b9c1b51eSKate Stone   void MonitorTrace(NativeThreadLinux &thread);
178c16f5dcaSChaoren Lin 
179b9c1b51eSKate Stone   void MonitorBreakpoint(NativeThreadLinux &thread);
180c16f5dcaSChaoren Lin 
181b9c1b51eSKate Stone   void MonitorWatchpoint(NativeThreadLinux &thread, uint32_t wp_index);
182c16f5dcaSChaoren Lin 
183fdd741ddSPavel Labath   void MonitorSignal(const siginfo_t &info, NativeThreadLinux &thread);
184af245d11STodd Fiala 
185b9c1b51eSKate Stone   bool HasThreadNoLock(lldb::tid_t thread_id);
186af245d11STodd Fiala 
187ca271f4eSPavel Labath   void StopTrackingThread(NativeThreadLinux &thread);
188af245d11STodd Fiala 
1890b697561SWalter Erquinigo   /// Create a new thread.
1900b697561SWalter Erquinigo   ///
1910b697561SWalter Erquinigo   /// If process tracing is enabled and the thread can't be traced, then the
1920b697561SWalter Erquinigo   /// thread is left stopped with a \a eStopReasonProcessorTrace status, and
1930b697561SWalter Erquinigo   /// then the process is stopped.
1940b697561SWalter Erquinigo   ///
1950b697561SWalter Erquinigo   /// \param[in] resume
1960b697561SWalter Erquinigo   ///     If a tracing error didn't happen, then resume the thread after
1970b697561SWalter Erquinigo   ///     creation if \b true, or leave it stopped with SIGSTOP if \b false.
1980b697561SWalter Erquinigo   NativeThreadLinux &AddThread(lldb::tid_t thread_id, bool resume);
1990b697561SWalter Erquinigo 
2000b697561SWalter Erquinigo   /// Start tracing a new thread if process tracing is enabled.
2010b697561SWalter Erquinigo   ///
2020b697561SWalter Erquinigo   /// Trace mechanisms should modify this method to provide automatic tracing
2030b697561SWalter Erquinigo   /// for new threads.
2040b697561SWalter Erquinigo   Status NotifyTracersOfNewThread(lldb::tid_t tid);
2050b697561SWalter Erquinigo 
2060b697561SWalter Erquinigo   /// Stop tracing threads upon a destroy event.
2070b697561SWalter Erquinigo   ///
2080b697561SWalter Erquinigo   /// Trace mechanisms should modify this method to provide automatic trace
2090b697561SWalter Erquinigo   /// stopping for threads being destroyed.
2100b697561SWalter Erquinigo   Status NotifyTracersOfThreadDestroyed(lldb::tid_t tid);
211af245d11STodd Fiala 
212*a7582059SWalter Erquinigo   void NotifyTracersProcessWillResume() override;
213*a7582059SWalter Erquinigo 
214*a7582059SWalter Erquinigo   void NotifyTracersProcessDidStop() override;
2151637545fSWalter Erquinigo 
216af245d11STodd Fiala   /// Writes the raw event message code (vis-a-vis PTRACE_GETEVENTMSG)
217af245d11STodd Fiala   /// corresponding to the given thread ID to the memory pointed to by @p
218af245d11STodd Fiala   /// message.
21997206d57SZachary Turner   Status GetEventMessage(lldb::tid_t tid, unsigned long *message);
220af245d11STodd Fiala 
221b9c1b51eSKate Stone   void NotifyThreadDeath(lldb::tid_t tid);
222fa03ad2eSChaoren Lin 
22397206d57SZachary Turner   Status Detach(lldb::tid_t tid);
22486fd8e45SChaoren Lin 
225b9c1b51eSKate Stone   // This method is requests a stop on all threads which are still running. It
226b9c1b51eSKate Stone   // sets up a
227b9c1b51eSKate Stone   // deferred delegate notification, which will fire once threads report as
228b9c1b51eSKate Stone   // stopped. The
2291dbc6c9cSPavel Labath   // triggerring_tid will be set as the current thread (main stop reason).
230b9c1b51eSKate Stone   void StopRunningThreads(lldb::tid_t triggering_tid);
231c076559aSPavel Labath 
2329eb1ecb9SPavel Labath   // Notify the delegate if all threads have stopped.
2339eb1ecb9SPavel Labath   void SignalIfAllThreadsStopped();
234c076559aSPavel Labath 
235b9c1b51eSKate Stone   // Resume the given thread, optionally passing it the given signal. The type
236b9c1b51eSKate Stone   // of resume
2370e1d729bSPavel Labath   // operation (continue, single-step) depends on the state parameter.
23897206d57SZachary Turner   Status ResumeThread(NativeThreadLinux &thread, lldb::StateType state,
239b9c1b51eSKate Stone                       int signo);
240c076559aSPavel Labath 
241b9c1b51eSKate Stone   void ThreadWasCreated(NativeThreadLinux &thread);
242c076559aSPavel Labath 
243b9c1b51eSKate Stone   void SigchldHandler();
244a6f5795aSTamas Berghammer 
24597206d57SZachary Turner   Status PopulateMemoryRegionCache();
24699e37695SRavitheja Addepally 
2470b697561SWalter Erquinigo   /// Manages Intel PT process and thread traces.
24822077627SJakob Johnson   IntelPTCollector m_intel_pt_collector;
249c8d18cbaSMichał Górny 
250ca271f4eSPavel Labath   // Handle a clone()-like event.
251ca271f4eSPavel Labath   bool MonitorClone(NativeThreadLinux &parent, lldb::pid_t child_pid,
252ca271f4eSPavel Labath                     int event);
253af245d11STodd Fiala };
254db264a6dSTamas Berghammer 
255db264a6dSTamas Berghammer } // namespace process_linux
256db264a6dSTamas Berghammer } // namespace lldb_private
257af245d11STodd Fiala 
258af245d11STodd Fiala #endif // #ifndef liblldb_NativeProcessLinux_H_
259