//===-- ProcessFreeBSD.h ------------------------------------------*- C++ //-*-===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// #ifndef liblldb_ProcessFreeBSD_H_ #define liblldb_ProcessFreeBSD_H_ #include "Plugins/Process/POSIX/ProcessMessage.h" #include "lldb/Target/Process.h" #include "lldb/Target/ThreadList.h" #include #include #include class ProcessMonitor; class FreeBSDThread; class ProcessFreeBSD : public lldb_private::Process { public: // Static functions. static lldb::ProcessSP CreateInstance(lldb::TargetSP target_sp, lldb::ListenerSP listener_sp, const lldb_private::FileSpec *crash_file_path, bool can_connect); static void Initialize(); static void Terminate(); static lldb_private::ConstString GetPluginNameStatic(); static const char *GetPluginDescriptionStatic(); // Constructors and destructors ProcessFreeBSD(lldb::TargetSP target_sp, lldb::ListenerSP listener_sp, lldb::UnixSignalsSP &unix_signals_sp); ~ProcessFreeBSD(); virtual lldb_private::Status WillResume() override; // PluginInterface protocol virtual lldb_private::ConstString GetPluginName() override; virtual uint32_t GetPluginVersion() override; public: // Process protocol. void Finalize() override; bool CanDebug(lldb::TargetSP target_sp, bool plugin_specified_by_name) override; lldb_private::Status WillLaunch(lldb_private::Module *module) override; lldb_private::Status DoAttachToProcessWithID( lldb::pid_t pid, const lldb_private::ProcessAttachInfo &attach_info) override; lldb_private::Status DoLaunch(lldb_private::Module *exe_module, lldb_private::ProcessLaunchInfo &launch_info) override; void DidLaunch() override; lldb_private::Status DoResume() override; lldb_private::Status DoHalt(bool &caused_stop) override; lldb_private::Status DoDetach(bool keep_stopped) override; lldb_private::Status DoSignal(int signal) override; lldb_private::Status DoDestroy() override; void DoDidExec() override; void RefreshStateAfterStop() override; bool IsAlive() override; size_t DoReadMemory(lldb::addr_t vm_addr, void *buf, size_t size, lldb_private::Status &error) override; size_t DoWriteMemory(lldb::addr_t vm_addr, const void *buf, size_t size, lldb_private::Status &error) override; lldb::addr_t DoAllocateMemory(size_t size, uint32_t permissions, lldb_private::Status &error) override; lldb_private::Status DoDeallocateMemory(lldb::addr_t ptr) override; virtual size_t GetSoftwareBreakpointTrapOpcode(lldb_private::BreakpointSite *bp_site); lldb_private::Status EnableBreakpointSite(lldb_private::BreakpointSite *bp_site) override; lldb_private::Status DisableBreakpointSite(lldb_private::BreakpointSite *bp_site) override; lldb_private::Status EnableWatchpoint(lldb_private::Watchpoint *wp, bool notify = true) override; lldb_private::Status DisableWatchpoint(lldb_private::Watchpoint *wp, bool notify = true) override; lldb_private::Status GetWatchpointSupportInfo(uint32_t &num) override; lldb_private::Status GetWatchpointSupportInfo(uint32_t &num, bool &after) override; virtual uint32_t UpdateThreadListIfNeeded(); bool UpdateThreadList(lldb_private::ThreadList &old_thread_list, lldb_private::ThreadList &new_thread_list) override; virtual lldb::ByteOrder GetByteOrder() const; lldb::addr_t GetImageInfoAddress() override; size_t PutSTDIN(const char *buf, size_t len, lldb_private::Status &error) override; lldb_private::DataExtractor GetAuxvData() override; // ProcessFreeBSD internal API. /// Registers the given message with this process. virtual void SendMessage(const ProcessMessage &message); ProcessMonitor &GetMonitor() { assert(m_monitor); return *m_monitor; } lldb_private::FileSpec GetFileSpec(const lldb_private::FileAction *file_action, const lldb_private::FileSpec &default_file_spec, const lldb_private::FileSpec &dbg_pts_file_spec); /// Adds the thread to the list of threads for which we have received the /// initial stopping signal. /// The \p stop_tid parameter indicates the thread which the stop happened /// for. bool AddThreadForInitialStopIfNeeded(lldb::tid_t stop_tid); bool WaitingForInitialStop(lldb::tid_t stop_tid); virtual FreeBSDThread *CreateNewFreeBSDThread(lldb_private::Process &process, lldb::tid_t tid); static bool SingleStepBreakpointHit( void *baton, lldb_private::StoppointCallbackContext *context, lldb::user_id_t break_id, lldb::user_id_t break_loc_id); lldb_private::Status SetupSoftwareSingleStepping(lldb::tid_t tid); lldb_private::Status SetSoftwareSingleStepBreakpoint(lldb::tid_t tid, lldb::addr_t addr); bool IsSoftwareStepBreakpoint(lldb::tid_t tid); bool SupportHardwareSingleStepping() const; typedef std::vector tid_collection; tid_collection &GetStepTids() { return m_step_tids; } protected: static const size_t MAX_TRAP_OPCODE_SIZE = 8; /// Target byte order. lldb::ByteOrder m_byte_order; /// Process monitor; ProcessMonitor *m_monitor; /// The module we are executing. lldb_private::Module *m_module; /// Message queue notifying this instance of inferior process state changes. std::recursive_mutex m_message_mutex; std::queue m_message_queue; /// Drive any exit events to completion. bool m_exit_now; /// Returns true if the process has exited. bool HasExited(); /// Returns true if the process is stopped. bool IsStopped(); /// Returns true if at least one running is currently running bool IsAThreadRunning(); typedef std::map MMapMap; MMapMap m_addr_to_mmap_size; typedef std::set ThreadStopSet; /// Every thread begins with a stop signal. This keeps track /// of the threads for which we have received the stop signal. ThreadStopSet m_seen_initial_stop; friend class FreeBSDThread; tid_collection m_suspend_tids; tid_collection m_run_tids; tid_collection m_step_tids; std::map m_threads_stepping_with_breakpoint; int m_resume_signo; }; #endif // liblldb_ProcessFreeBSD_H_