Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-05-10 08:42:48

0001 //===-- NativeProcessProtocol.h ---------------------------------*- C++ -*-===//
0002 //
0003 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
0004 // See https://llvm.org/LICENSE.txt for license information.
0005 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
0006 //
0007 //===----------------------------------------------------------------------===//
0008 
0009 #ifndef LLDB_HOST_COMMON_NATIVEPROCESSPROTOCOL_H
0010 #define LLDB_HOST_COMMON_NATIVEPROCESSPROTOCOL_H
0011 
0012 #include "NativeBreakpointList.h"
0013 #include "NativeThreadProtocol.h"
0014 #include "NativeWatchpointList.h"
0015 #include "lldb/Host/Host.h"
0016 #include "lldb/Host/MainLoop.h"
0017 #include "lldb/Utility/ArchSpec.h"
0018 #include "lldb/Utility/Iterable.h"
0019 #include "lldb/Utility/Status.h"
0020 #include "lldb/Utility/TraceGDBRemotePackets.h"
0021 #include "lldb/Utility/UnimplementedError.h"
0022 #include "lldb/lldb-private-forward.h"
0023 #include "lldb/lldb-types.h"
0024 #include "llvm/ADT/ArrayRef.h"
0025 #include "llvm/ADT/DenseSet.h"
0026 #include "llvm/ADT/StringRef.h"
0027 #include "llvm/Support/Error.h"
0028 #include "llvm/Support/MemoryBuffer.h"
0029 #include <mutex>
0030 #include <optional>
0031 #include <unordered_map>
0032 #include <vector>
0033 
0034 namespace lldb_private {
0035 LLVM_ENABLE_BITMASK_ENUMS_IN_NAMESPACE();
0036 
0037 class MemoryRegionInfo;
0038 class ResumeActionList;
0039 
0040 struct SVR4LibraryInfo {
0041   std::string name;
0042   lldb::addr_t link_map;
0043   lldb::addr_t base_addr;
0044   lldb::addr_t ld_addr;
0045   lldb::addr_t next;
0046 };
0047 
0048 // NativeProcessProtocol
0049 class NativeProcessProtocol {
0050 public:
0051   virtual ~NativeProcessProtocol() = default;
0052 
0053   typedef std::vector<std::unique_ptr<NativeThreadProtocol>> thread_collection;
0054   template <typename I>
0055   static NativeThreadProtocol &thread_list_adapter(I &iter) {
0056     assert(*iter);
0057     return **iter;
0058   }
0059   typedef LockingAdaptedIterable<thread_collection, NativeThreadProtocol &,
0060                                  thread_list_adapter, std::recursive_mutex>
0061       ThreadIterable;
0062 
0063   virtual Status Resume(const ResumeActionList &resume_actions) = 0;
0064 
0065   virtual Status Halt() = 0;
0066 
0067   virtual Status Detach() = 0;
0068 
0069   /// Sends a process a UNIX signal \a signal.
0070   ///
0071   /// \return
0072   ///     Returns an error object.
0073   virtual Status Signal(int signo) = 0;
0074 
0075   /// Tells a process to interrupt all operations as if by a Ctrl-C.
0076   ///
0077   /// The default implementation will send a local host's equivalent of
0078   /// a SIGSTOP to the process via the NativeProcessProtocol::Signal()
0079   /// operation.
0080   ///
0081   /// \return
0082   ///     Returns an error object.
0083   virtual Status Interrupt();
0084 
0085   virtual Status Kill() = 0;
0086 
0087   // Tells a process not to stop the inferior on given signals and just
0088   // reinject them back.
0089   virtual Status IgnoreSignals(llvm::ArrayRef<int> signals);
0090 
0091   // Memory and memory region functions
0092 
0093   virtual Status GetMemoryRegionInfo(lldb::addr_t load_addr,
0094                                      MemoryRegionInfo &range_info);
0095 
0096   virtual Status ReadMemory(lldb::addr_t addr, void *buf, size_t size,
0097                             size_t &bytes_read) = 0;
0098 
0099   Status ReadMemoryWithoutTrap(lldb::addr_t addr, void *buf, size_t size,
0100                                size_t &bytes_read);
0101 
0102   virtual Status ReadMemoryTags(int32_t type, lldb::addr_t addr, size_t len,
0103                                 std::vector<uint8_t> &tags);
0104 
0105   virtual Status WriteMemoryTags(int32_t type, lldb::addr_t addr, size_t len,
0106                                  const std::vector<uint8_t> &tags);
0107 
0108   /// Reads a null terminated string from memory.
0109   ///
0110   /// Reads up to \p max_size bytes of memory until it finds a '\0'.
0111   /// If a '\0' is not found then it reads max_size-1 bytes as a string and a
0112   /// '\0' is added as the last character of the \p buffer.
0113   ///
0114   /// \param[in] addr
0115   ///     The address in memory to read from.
0116   ///
0117   /// \param[in] buffer
0118   ///     An allocated buffer with at least \p max_size size.
0119   ///
0120   /// \param[in] max_size
0121   ///     The maximum number of bytes to read from memory until it reads the
0122   ///     string.
0123   ///
0124   /// \param[out] total_bytes_read
0125   ///     The number of bytes read from memory into \p buffer.
0126   ///
0127   /// \return
0128   ///     Returns a StringRef backed up by the \p buffer passed in.
0129   llvm::Expected<llvm::StringRef>
0130   ReadCStringFromMemory(lldb::addr_t addr, char *buffer, size_t max_size,
0131                         size_t &total_bytes_read);
0132 
0133   virtual Status WriteMemory(lldb::addr_t addr, const void *buf, size_t size,
0134                              size_t &bytes_written) = 0;
0135 
0136   virtual llvm::Expected<lldb::addr_t> AllocateMemory(size_t size,
0137                                                       uint32_t permissions) {
0138     return llvm::make_error<UnimplementedError>();
0139   }
0140 
0141   virtual llvm::Error DeallocateMemory(lldb::addr_t addr) {
0142     return llvm::make_error<UnimplementedError>();
0143   }
0144 
0145   virtual lldb::addr_t GetSharedLibraryInfoAddress() = 0;
0146 
0147   virtual llvm::Expected<std::vector<SVR4LibraryInfo>>
0148   GetLoadedSVR4Libraries() {
0149     return llvm::createStringError(llvm::inconvertibleErrorCode(),
0150                                    "Not implemented");
0151   }
0152 
0153   virtual bool IsAlive() const;
0154 
0155   virtual size_t UpdateThreads() = 0;
0156 
0157   virtual const ArchSpec &GetArchitecture() const = 0;
0158 
0159   // Breakpoint functions
0160   virtual Status SetBreakpoint(lldb::addr_t addr, uint32_t size,
0161                                bool hardware) = 0;
0162 
0163   virtual Status RemoveBreakpoint(lldb::addr_t addr, bool hardware = false);
0164 
0165   // Hardware Breakpoint functions
0166   virtual const HardwareBreakpointMap &GetHardwareBreakpointMap() const;
0167 
0168   virtual Status SetHardwareBreakpoint(lldb::addr_t addr, size_t size);
0169 
0170   virtual Status RemoveHardwareBreakpoint(lldb::addr_t addr);
0171 
0172   // Watchpoint functions
0173   virtual const NativeWatchpointList::WatchpointMap &GetWatchpointMap() const;
0174 
0175   virtual std::optional<std::pair<uint32_t, uint32_t>>
0176   GetHardwareDebugSupportInfo() const;
0177 
0178   virtual Status SetWatchpoint(lldb::addr_t addr, size_t size,
0179                                uint32_t watch_flags, bool hardware);
0180 
0181   virtual Status RemoveWatchpoint(lldb::addr_t addr);
0182 
0183   // Accessors
0184   lldb::pid_t GetID() const { return m_pid; }
0185 
0186   lldb::StateType GetState() const;
0187 
0188   bool IsRunning() const {
0189     return m_state == lldb::eStateRunning || IsStepping();
0190   }
0191 
0192   bool IsStepping() const { return m_state == lldb::eStateStepping; }
0193 
0194   bool CanResume() const { return m_state == lldb::eStateStopped; }
0195 
0196   lldb::ByteOrder GetByteOrder() const {
0197     return GetArchitecture().GetByteOrder();
0198   }
0199 
0200   uint32_t GetAddressByteSize() const {
0201     return GetArchitecture().GetAddressByteSize();
0202   }
0203 
0204   virtual llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>>
0205   GetAuxvData() const = 0;
0206 
0207   // Exit Status
0208   virtual std::optional<WaitStatus> GetExitStatus();
0209 
0210   virtual bool SetExitStatus(WaitStatus status, bool bNotifyStateChange);
0211 
0212   // Access to threads
0213   NativeThreadProtocol *GetThreadAtIndex(uint32_t idx);
0214 
0215   NativeThreadProtocol *GetThreadByID(lldb::tid_t tid);
0216 
0217   void SetCurrentThreadID(lldb::tid_t tid) { m_current_thread_id = tid; }
0218 
0219   lldb::tid_t GetCurrentThreadID() const { return m_current_thread_id; }
0220 
0221   NativeThreadProtocol *GetCurrentThread() {
0222     return GetThreadByID(m_current_thread_id);
0223   }
0224 
0225   ThreadIterable Threads() const {
0226     return ThreadIterable(m_threads, m_threads_mutex);
0227   }
0228 
0229   // Access to inferior stdio
0230   virtual int GetTerminalFileDescriptor() { return m_terminal_fd; }
0231 
0232   // Stop id interface
0233 
0234   uint32_t GetStopID() const;
0235 
0236   // Callbacks for low-level process state changes
0237   class NativeDelegate {
0238   public:
0239     virtual ~NativeDelegate() = default;
0240 
0241     virtual void InitializeDelegate(NativeProcessProtocol *process) = 0;
0242 
0243     virtual void ProcessStateChanged(NativeProcessProtocol *process,
0244                                      lldb::StateType state) = 0;
0245 
0246     virtual void DidExec(NativeProcessProtocol *process) = 0;
0247 
0248     virtual void
0249     NewSubprocess(NativeProcessProtocol *parent_process,
0250                   std::unique_ptr<NativeProcessProtocol> child_process) = 0;
0251   };
0252 
0253   virtual Status GetLoadedModuleFileSpec(const char *module_path,
0254                                          FileSpec &file_spec) = 0;
0255 
0256   virtual Status GetFileLoadAddress(const llvm::StringRef &file_name,
0257                                     lldb::addr_t &load_addr) = 0;
0258 
0259   /// Extension flag constants, returned by Manager::GetSupportedExtensions()
0260   /// and passed to SetEnabledExtension()
0261   enum class Extension {
0262     multiprocess = (1u << 0),
0263     fork = (1u << 1),
0264     vfork = (1u << 2),
0265     pass_signals = (1u << 3),
0266     auxv = (1u << 4),
0267     libraries_svr4 = (1u << 5),
0268     memory_tagging = (1u << 6),
0269     savecore = (1u << 7),
0270     siginfo_read = (1u << 8),
0271 
0272     LLVM_MARK_AS_BITMASK_ENUM(siginfo_read)
0273   };
0274 
0275   class Manager {
0276   public:
0277     Manager(MainLoop &mainloop) : m_mainloop(mainloop) {}
0278     Manager(const Manager &) = delete;
0279     Manager &operator=(const Manager &) = delete;
0280 
0281     virtual ~Manager();
0282 
0283     /// Launch a process for debugging.
0284     ///
0285     /// \param[in] launch_info
0286     ///     Information required to launch the process.
0287     ///
0288     /// \param[in] native_delegate
0289     ///     The delegate that will receive messages regarding the
0290     ///     inferior.  Must outlive the NativeProcessProtocol
0291     ///     instance.
0292     ///
0293     /// \param[in] mainloop
0294     ///     The mainloop instance with which the process can register
0295     ///     callbacks. Must outlive the NativeProcessProtocol
0296     ///     instance.
0297     ///
0298     /// \return
0299     ///     A NativeProcessProtocol shared pointer if the operation succeeded or
0300     ///     an error object if it failed.
0301     virtual llvm::Expected<std::unique_ptr<NativeProcessProtocol>>
0302     Launch(ProcessLaunchInfo &launch_info,
0303            NativeDelegate &native_delegate) = 0;
0304 
0305     /// Attach to an existing process.
0306     ///
0307     /// \param[in] pid
0308     ///     pid of the process locatable
0309     ///
0310     /// \param[in] native_delegate
0311     ///     The delegate that will receive messages regarding the
0312     ///     inferior.  Must outlive the NativeProcessProtocol
0313     ///     instance.
0314     ///
0315     /// \param[in] mainloop
0316     ///     The mainloop instance with which the process can register
0317     ///     callbacks. Must outlive the NativeProcessProtocol
0318     ///     instance.
0319     ///
0320     /// \return
0321     ///     A NativeProcessProtocol shared pointer if the operation succeeded or
0322     ///     an error object if it failed.
0323     virtual llvm::Expected<std::unique_ptr<NativeProcessProtocol>>
0324     Attach(lldb::pid_t pid, NativeDelegate &native_delegate) = 0;
0325 
0326     /// Get the bitmask of extensions supported by this process plugin.
0327     ///
0328     /// \return
0329     ///     A NativeProcessProtocol::Extension bitmask.
0330     virtual Extension GetSupportedExtensions() const { return {}; }
0331 
0332   protected:
0333     MainLoop &m_mainloop;
0334   };
0335 
0336   /// Notify tracers that the target process will resume
0337   virtual void NotifyTracersProcessWillResume() {}
0338 
0339   /// Notify tracers that the target process just stopped
0340   virtual void NotifyTracersProcessDidStop() {}
0341 
0342   /// Start tracing a process or its threads.
0343   ///
0344   /// \param[in] json_params
0345   ///     JSON object with the information of what and how to trace.
0346   ///     In the case of gdb-remote, this object should conform to the
0347   ///     jLLDBTraceStart packet.
0348   ///
0349   ///     This object should have a string entry called "type", which is the
0350   ///     tracing technology name.
0351   ///
0352   /// \param[in] type
0353   ///     Tracing technology type, as described in the \a json_params.
0354   ///
0355   /// \return
0356   ///     \a llvm::Error::success if the operation was successful, or an
0357   ///     \a llvm::Error otherwise.
0358   virtual llvm::Error TraceStart(llvm::StringRef json_params,
0359                                  llvm::StringRef type) {
0360     return llvm::createStringError(llvm::inconvertibleErrorCode(),
0361                                    "Unsupported tracing type '%s'",
0362                                    type.data());
0363   }
0364 
0365   /// \copydoc Process::TraceStop(const TraceStopRequest &)
0366   virtual llvm::Error TraceStop(const TraceStopRequest &request) {
0367     return llvm::createStringError(llvm::inconvertibleErrorCode(),
0368                                    "Unsupported tracing type '%s'",
0369                                    request.type.data());
0370   }
0371 
0372   /// \copydoc Process::TraceGetState(llvm::StringRef type)
0373   virtual llvm::Expected<llvm::json::Value>
0374   TraceGetState(llvm::StringRef type) {
0375     return llvm::createStringError(llvm::inconvertibleErrorCode(),
0376                                    "Unsupported tracing type '%s'",
0377                                    type.data());
0378   }
0379 
0380   /// \copydoc Process::TraceGetBinaryData(const TraceGetBinaryDataRequest &)
0381   virtual llvm::Expected<std::vector<uint8_t>>
0382   TraceGetBinaryData(const TraceGetBinaryDataRequest &request) {
0383     return llvm::createStringError(
0384         llvm::inconvertibleErrorCode(),
0385         "Unsupported data kind '%s' for the '%s' tracing technology",
0386         request.kind.c_str(), request.type.c_str());
0387   }
0388 
0389   /// \copydoc Process::TraceSupported()
0390   virtual llvm::Expected<TraceSupportedResponse> TraceSupported() {
0391     return llvm::make_error<UnimplementedError>();
0392   }
0393 
0394   /// Method called in order to propagate the bitmap of protocol
0395   /// extensions supported by the client.
0396   ///
0397   /// \param[in] flags
0398   ///     The bitmap of enabled extensions.
0399   virtual void SetEnabledExtensions(Extension flags) {
0400     m_enabled_extensions = flags;
0401   }
0402 
0403   /// Write a core dump (without crashing the program).
0404   ///
0405   /// \param[in] path_hint
0406   ///     Suggested core dump path (optional, can be empty).
0407   ///
0408   /// \return
0409   ///     Path to the core dump if successfully written, an error
0410   ///     otherwise.
0411   virtual llvm::Expected<std::string> SaveCore(llvm::StringRef path_hint) {
0412     return llvm::createStringError(llvm::inconvertibleErrorCode(),
0413                                    "Not implemented");
0414   }
0415 
0416 protected:
0417   struct SoftwareBreakpoint {
0418     uint32_t ref_count;
0419     llvm::SmallVector<uint8_t, 4> saved_opcodes;
0420     llvm::ArrayRef<uint8_t> breakpoint_opcodes;
0421   };
0422 
0423   std::unordered_map<lldb::addr_t, SoftwareBreakpoint> m_software_breakpoints;
0424   lldb::pid_t m_pid;
0425 
0426   std::vector<std::unique_ptr<NativeThreadProtocol>> m_threads;
0427   lldb::tid_t m_current_thread_id = LLDB_INVALID_THREAD_ID;
0428   mutable std::recursive_mutex m_threads_mutex;
0429 
0430   lldb::StateType m_state = lldb::eStateInvalid;
0431   mutable std::recursive_mutex m_state_mutex;
0432 
0433   std::optional<WaitStatus> m_exit_status;
0434 
0435   NativeDelegate &m_delegate;
0436   NativeWatchpointList m_watchpoint_list;
0437   HardwareBreakpointMap m_hw_breakpoints_map;
0438   int m_terminal_fd;
0439   uint32_t m_stop_id = 0;
0440 
0441   // Set of signal numbers that LLDB directly injects back to inferior without
0442   // stopping it.
0443   llvm::DenseSet<int> m_signals_to_ignore;
0444 
0445   // Extensions enabled per the last SetEnabledExtensions() call.
0446   Extension m_enabled_extensions;
0447 
0448   // lldb_private::Host calls should be used to launch a process for debugging,
0449   // and then the process should be attached to. When attaching to a process
0450   // lldb_private::Host calls should be used to locate the process to attach
0451   // to, and then this function should be called.
0452   NativeProcessProtocol(lldb::pid_t pid, int terminal_fd,
0453                         NativeDelegate &delegate);
0454 
0455   void SetID(lldb::pid_t pid) { m_pid = pid; }
0456 
0457   // interface for state handling
0458   void SetState(lldb::StateType state, bool notify_delegates = true);
0459 
0460   // Derived classes need not implement this.  It can be used as a hook to
0461   // clear internal caches that should be invalidated when stop ids change.
0462   //
0463   // Note this function is called with the state mutex obtained by the caller.
0464   virtual void DoStopIDBumped(uint32_t newBumpId);
0465 
0466   // interface for software breakpoints
0467 
0468   Status SetSoftwareBreakpoint(lldb::addr_t addr, uint32_t size_hint);
0469   Status RemoveSoftwareBreakpoint(lldb::addr_t addr);
0470 
0471   virtual llvm::Expected<llvm::ArrayRef<uint8_t>>
0472   GetSoftwareBreakpointTrapOpcode(size_t size_hint);
0473 
0474   /// Return the offset of the PC relative to the software breakpoint that was hit. If an
0475   /// architecture (e.g. arm) reports breakpoint hits before incrementing the PC, this offset
0476   /// will be 0. If an architecture (e.g. intel) reports breakpoints hits after incrementing the
0477   /// PC, this offset will be the size of the breakpoint opcode.
0478   virtual size_t GetSoftwareBreakpointPCOffset();
0479 
0480   // Adjust the thread's PC after hitting a software breakpoint. On
0481   // architectures where the PC points after the breakpoint instruction, this
0482   // resets it to point to the breakpoint itself.
0483   void FixupBreakpointPCAsNeeded(NativeThreadProtocol &thread);
0484 
0485   /// Notify the delegate that an exec occurred.
0486   ///
0487   /// Provide a mechanism for a delegate to clear out any exec-
0488   /// sensitive data.
0489   virtual void NotifyDidExec();
0490 
0491   NativeThreadProtocol *GetThreadByIDUnlocked(lldb::tid_t tid);
0492 
0493 private:
0494   void SynchronouslyNotifyProcessStateChanged(lldb::StateType state);
0495   llvm::Expected<SoftwareBreakpoint>
0496   EnableSoftwareBreakpoint(lldb::addr_t addr, uint32_t size_hint);
0497 };
0498 } // namespace lldb_private
0499 
0500 #endif // LLDB_HOST_COMMON_NATIVEPROCESSPROTOCOL_H