diff options
author | Dimitry Andric <dim@FreeBSD.org> | 2016-07-23 20:50:09 +0000 |
---|---|---|
committer | Dimitry Andric <dim@FreeBSD.org> | 2016-07-23 20:50:09 +0000 |
commit | f3fbd1c0586ff6ec7895991e6c28f61a503c36a8 (patch) | |
tree | 48d008fd3df8c0e73271a4b18474e0aac6dbfe33 /include/lldb/Core | |
parent | 2fc5d2d1dfaf623ce4e24cd8590565902f8c557c (diff) |
Notes
Diffstat (limited to 'include/lldb/Core')
36 files changed, 1021 insertions, 435 deletions
diff --git a/include/lldb/Core/ArchSpec.h b/include/lldb/Core/ArchSpec.h index 13ff436cf08f6..be760637c03e8 100644 --- a/include/lldb/Core/ArchSpec.h +++ b/include/lldb/Core/ArchSpec.h @@ -69,9 +69,33 @@ public: eMIPSABI_O32 = 0x00002000, eMIPSABI_N32 = 0x00004000, eMIPSABI_N64 = 0x00008000, + eMIPSABI_O64 = 0x00020000, + eMIPSABI_EABI32 = 0x00040000, + eMIPSABI_EABI64 = 0x00080000, eMIPSABI_mask = 0x000ff000 }; + // MIPS Floating point ABI Values + enum MIPS_ABI_FP + { + eMIPS_ABI_FP_ANY = 0x00000000, + eMIPS_ABI_FP_DOUBLE = 0x00100000, // hard float / -mdouble-float + eMIPS_ABI_FP_SINGLE = 0x00200000, // hard float / -msingle-float + eMIPS_ABI_FP_SOFT = 0x00300000, // soft float + eMIPS_ABI_FP_OLD_64 = 0x00400000, // -mips32r2 -mfp64 + eMIPS_ABI_FP_XX = 0x00500000, // -mfpxx + eMIPS_ABI_FP_64 = 0x00600000, // -mips32r2 -mfp64 + eMIPS_ABI_FP_64A = 0x00700000, // -mips32r2 -mfp64 -mno-odd-spreg + eMIPS_ABI_FP_mask = 0x00700000 + }; + + // ARM specific e_flags + enum ARMeflags + { + eARM_abi_soft_float = 0x00000200, + eARM_abi_hard_float = 0x00000400 + }; + enum Core { eCore_arm_generic, @@ -144,6 +168,8 @@ public: eCore_ppc64_generic, eCore_ppc64_ppc970_64, + eCore_s390x_generic, + eCore_sparc_generic, eCore_sparc9_generic, @@ -280,6 +306,24 @@ public: const char * GetArchitectureName () const; + //----------------------------------------------------------------- + /// if MIPS architecture return true. + /// + /// @return a boolean value. + //----------------------------------------------------------------- + bool + IsMIPS() const; + + //------------------------------------------------------------------ + /// Returns a string representing current architecture as a target CPU + /// for tools like compiler, disassembler etc. + /// + /// @return A string representing target CPU for the current + /// architecture. + //------------------------------------------------------------------ + std::string + GetClangTargetCPU (); + //------------------------------------------------------------------ /// Clears the object state. /// @@ -605,6 +649,22 @@ public: bool &os_version_different, bool &env_different); + //------------------------------------------------------------------ + /// Detect whether this architecture uses thumb code exclusively + /// + /// Some embedded ARM chips (e.g. the ARM Cortex M0-7 line) can + /// only execute the Thumb instructions, never Arm. We should normally + /// pick up arm/thumbness from their the processor status bits (cpsr/xpsr) + /// or hints on each function - but when doing bare-boards low level + /// debugging (especially common with these embedded processors), we may + /// not have those things easily accessible. + /// + /// @return true if this is an arm ArchSpec which can only execute Thumb + /// instructions + //------------------------------------------------------------------ + bool + IsAlwaysThumbInstructions () const; + uint32_t GetFlags () const { diff --git a/include/lldb/Core/Broadcaster.h b/include/lldb/Core/Broadcaster.h index 8e59a41805ece..33172fa73780a 100644 --- a/include/lldb/Core/Broadcaster.h +++ b/include/lldb/Core/Broadcaster.h @@ -12,16 +12,17 @@ // C Includes // C++ Includes +#include <functional> +#include <list> #include <map> +#include <mutex> #include <string> #include <vector> // Other libraries and framework includes // Project includes #include "lldb/lldb-private.h" -//#include "lldb/Core/Flags.h" #include "lldb/Core/ConstString.h" -#include "lldb/Core/Listener.h" namespace lldb_private { @@ -75,48 +76,58 @@ public: } bool operator< (const BroadcastEventSpec &rhs) const; - const BroadcastEventSpec &operator= (const BroadcastEventSpec &rhs); + BroadcastEventSpec &operator=(const BroadcastEventSpec &rhs); private: ConstString m_broadcaster_class; uint32_t m_event_bits; }; -class BroadcasterManager +class BroadcasterManager : + public std::enable_shared_from_this<BroadcasterManager> { public: friend class Listener; +protected: BroadcasterManager (); - +public: + // Listeners hold onto weak pointers to their broadcaster managers. So they must be + // made into shared pointers, which you do with MakeBroadcasterManager. + + static lldb::BroadcasterManagerSP + MakeBroadcasterManager(); + ~BroadcasterManager() = default; uint32_t - RegisterListenerForEvents (Listener &listener, BroadcastEventSpec event_spec); + RegisterListenerForEvents (const lldb::ListenerSP &listener_sp, BroadcastEventSpec event_spec); bool - UnregisterListenerForEvents (Listener &listener, BroadcastEventSpec event_spec); + UnregisterListenerForEvents (const lldb::ListenerSP &listener_sp, BroadcastEventSpec event_spec); - Listener * + lldb::ListenerSP GetListenerForEventSpec (BroadcastEventSpec event_spec) const; void SignUpListenersForBroadcaster (Broadcaster &broadcaster); void - RemoveListener (Listener &Listener); + RemoveListener (const lldb::ListenerSP &listener_sp); + + void + RemoveListener (Listener *listener); -protected: void Clear(); private: - typedef std::pair<BroadcastEventSpec, Listener *> event_listener_key; - typedef std::map<BroadcastEventSpec, Listener *> collection; - typedef std::set<Listener *> listener_collection; + typedef std::pair<BroadcastEventSpec, lldb::ListenerSP> event_listener_key; + typedef std::map<BroadcastEventSpec, lldb::ListenerSP> collection; + typedef std::set<lldb::ListenerSP> listener_collection; collection m_event_map; listener_collection m_listeners; - - Mutex m_manager_mutex; + + mutable std::recursive_mutex m_manager_mutex; // A couple of comparator classes for find_if: @@ -161,10 +172,9 @@ private: class ListenerMatchesAndSharedBits { public: - ListenerMatchesAndSharedBits (BroadcastEventSpec broadcaster_spec, - const Listener &listener) : + explicit ListenerMatchesAndSharedBits (BroadcastEventSpec broadcaster_spec, const lldb::ListenerSP listener_sp) : m_broadcaster_spec (broadcaster_spec), - m_listener (&listener) + m_listener_sp (listener_sp) { } @@ -174,19 +184,19 @@ private: { return (input.first.GetBroadcasterClass() == m_broadcaster_spec.GetBroadcasterClass() && (input.first.GetEventBits() & m_broadcaster_spec.GetEventBits()) != 0 - && input.second == m_listener); + && input.second == m_listener_sp); } private: BroadcastEventSpec m_broadcaster_spec; - const Listener *m_listener; + const lldb::ListenerSP m_listener_sp; }; class ListenerMatches { public: - ListenerMatches (const Listener &in_listener) : - m_listener (&in_listener) + explicit ListenerMatches (const lldb::ListenerSP in_listener_sp) : + m_listener_sp (in_listener_sp) { } @@ -194,15 +204,44 @@ private: bool operator () (const event_listener_key input) const { - if (input.second == m_listener) + if (input.second == m_listener_sp) return true; else return false; } private: - const Listener *m_listener; + const lldb::ListenerSP m_listener_sp; + }; + class ListenerMatchesPointer + { + public: + ListenerMatchesPointer (const Listener *in_listener) : + m_listener (in_listener) + { + } + + ~ListenerMatchesPointer() = default; + + bool operator () (const event_listener_key input) const + { + if (input.second.get() == m_listener) + return true; + else + return false; + } + + bool operator () (const lldb::ListenerSP input) const + { + if (input.get() == m_listener) + return true; + else + return false; + } + + private: + const Listener *m_listener; }; }; @@ -241,6 +280,8 @@ private: //---------------------------------------------------------------------- class Broadcaster { +friend class Listener; +friend class Event; public: //------------------------------------------------------------------ /// Construct with a broadcaster with a name. @@ -249,7 +290,7 @@ public: /// A NULL terminated C string that contains the name of the /// broadcaster object. //------------------------------------------------------------------ - Broadcaster (BroadcasterManager *manager, const char *name); + Broadcaster (lldb::BroadcasterManagerSP manager_sp, const char *name); //------------------------------------------------------------------ /// Destructor. @@ -279,22 +320,43 @@ public: /// //------------------------------------------------------------------ void - BroadcastEvent (lldb::EventSP &event_sp); + BroadcastEvent (lldb::EventSP &event_sp) + { + m_broadcaster_sp->BroadcastEvent(event_sp); + } void - BroadcastEventIfUnique (lldb::EventSP &event_sp); + BroadcastEventIfUnique (lldb::EventSP &event_sp) + { + m_broadcaster_sp->BroadcastEventIfUnique(event_sp); + } void - BroadcastEvent(uint32_t event_type, EventData *event_data = nullptr); + BroadcastEvent(uint32_t event_type, const lldb::EventDataSP &event_data_sp) + { + m_broadcaster_sp->BroadcastEvent(event_type, event_data_sp); + } void - BroadcastEventIfUnique(uint32_t event_type, EventData *event_data = nullptr); + BroadcastEvent(uint32_t event_type, EventData *event_data = nullptr) + { + m_broadcaster_sp->BroadcastEvent(event_type, event_data); + } void - Clear(); + BroadcastEventIfUnique(uint32_t event_type, EventData *event_data = nullptr) + { + m_broadcaster_sp->BroadcastEventIfUnique(event_type, event_data); + } + + void + Clear() + { + m_broadcaster_sp->Clear(); + } virtual void - AddInitialEventsToListener (Listener *listener, uint32_t requested_events); + AddInitialEventsToListener (const lldb::ListenerSP &listener_sp, uint32_t requested_events); //------------------------------------------------------------------ /// Listen for any events specified by \a event_mask. @@ -319,7 +381,10 @@ public: /// The actual event bits that were acquired by \a listener. //------------------------------------------------------------------ uint32_t - AddListener (Listener* listener, uint32_t event_mask); + AddListener (const lldb::ListenerSP &listener_sp, uint32_t event_mask) + { + return m_broadcaster_sp->AddListener(listener_sp, event_mask); + } //------------------------------------------------------------------ /// Get the NULL terminated C string name of this Broadcaster @@ -329,7 +394,10 @@ public: /// The NULL terminated C string name of this Broadcaster. //------------------------------------------------------------------ const ConstString & - GetBroadcasterName (); + GetBroadcasterName () + { + return m_broadcaster_name; + } //------------------------------------------------------------------ /// Get the event name(s) for one or more event bits. @@ -341,7 +409,10 @@ public: /// The NULL terminated C string name of this Broadcaster. //------------------------------------------------------------------ bool - GetEventNames (Stream &s, const uint32_t event_mask, bool prefix_with_broadcaster_name) const; + GetEventNames (Stream &s, const uint32_t event_mask, bool prefix_with_broadcaster_name) const + { + return m_broadcaster_sp->GetEventNames(s, event_mask, prefix_with_broadcaster_name); + } //------------------------------------------------------------------ /// Set the name for an event bit. @@ -356,20 +427,20 @@ public: void SetEventName (uint32_t event_mask, const char *name) { - m_event_names[event_mask] = name; + m_broadcaster_sp->SetEventName(event_mask, name); } const char * GetEventName (uint32_t event_mask) const { - const auto pos = m_event_names.find (event_mask); - if (pos != m_event_names.end()) - return pos->second.c_str(); - return nullptr; + return m_broadcaster_sp->GetEventName(event_mask); } bool - EventTypeHasListeners (uint32_t event_type); + EventTypeHasListeners (uint32_t event_type) + { + return m_broadcaster_sp->EventTypeHasListeners(event_type); + } //------------------------------------------------------------------ /// Removes a Listener from this broadcasters list and frees the @@ -390,7 +461,10 @@ public: /// @see uint32_t Broadcaster::AddListener (Listener*, uint32_t) //------------------------------------------------------------------ bool - RemoveListener (Listener* listener, uint32_t event_mask = UINT32_MAX); + RemoveListener (const lldb::ListenerSP &listener_sp, uint32_t event_mask = UINT32_MAX) + { + return m_broadcaster_sp->RemoveListener(listener_sp, event_mask); + } //------------------------------------------------------------------ /// Provides a simple mechanism to temporarily redirect events from @@ -414,17 +488,26 @@ public: /// @see uint32_t Broadcaster::AddListener (Listener*, uint32_t) //------------------------------------------------------------------ bool - HijackBroadcaster (Listener *listener, uint32_t event_mask = UINT32_MAX); + HijackBroadcaster (const lldb::ListenerSP &listener_sp, uint32_t event_mask = UINT32_MAX) + { + return m_broadcaster_sp->HijackBroadcaster(listener_sp, event_mask); + } bool - IsHijackedForEvent (uint32_t event_mask); + IsHijackedForEvent (uint32_t event_mask) + { + return m_broadcaster_sp->IsHijackedForEvent(event_mask); + } //------------------------------------------------------------------ /// Restore the state of the Broadcaster from a previous hijack attempt. /// //------------------------------------------------------------------ void - RestoreBroadcaster (); + RestoreBroadcaster () + { + m_broadcaster_sp->RestoreBroadcaster(); + } // This needs to be filled in if you are going to register the broadcaster with the broadcaster // manager and do broadcaster class matching. @@ -432,35 +515,158 @@ public: // with the BroadcasterManager, so that it is clearer how to add one. virtual ConstString &GetBroadcasterClass() const; - BroadcasterManager *GetManager(); + lldb::BroadcasterManagerSP GetManager(); protected: - void - PrivateBroadcastEvent (lldb::EventSP &event_sp, bool unique); + // BroadcasterImpl contains the actual Broadcaster implementation. The Broadcaster makes a BroadcasterImpl + // which lives as long as it does. The Listeners & the Events hold a weak pointer to the BroadcasterImpl, + // so that they can survive if a Broadcaster they were listening to is destroyed w/o their being able to + // unregister from it (which can happen if the Broadcasters & Listeners are being destroyed on separate threads + // simultaneously. + // The Broadcaster itself can't be shared out as a weak pointer, because some things that are broadcasters + // (e.g. the Target and the Process) are shared in their own right. + // + // For the most part, the Broadcaster functions dispatch to the BroadcasterImpl, and are documented in the + // public Broadcaster API above. + + + class BroadcasterImpl + { + friend class Listener; + friend class Broadcaster; + public: + BroadcasterImpl (Broadcaster &broadcaster); + + ~BroadcasterImpl() = default; + + void + BroadcastEvent (lldb::EventSP &event_sp); + + void + BroadcastEventIfUnique (lldb::EventSP &event_sp); + void + BroadcastEvent(uint32_t event_type, EventData *event_data = nullptr); + + void + BroadcastEvent(uint32_t event_type, const lldb::EventDataSP &event_data_sp); + + void + BroadcastEventIfUnique(uint32_t event_type, EventData *event_data = nullptr); + + void + Clear(); + + uint32_t + AddListener (const lldb::ListenerSP &listener_sp, uint32_t event_mask); + + const char * + GetBroadcasterName () const + { + return m_broadcaster.GetBroadcasterName().AsCString(); + } + + Broadcaster * + GetBroadcaster(); + + bool + GetEventNames (Stream &s, const uint32_t event_mask, bool prefix_with_broadcaster_name) const; + + void + SetEventName (uint32_t event_mask, const char *name) + { + m_event_names[event_mask] = name; + } + + const char * + GetEventName (uint32_t event_mask) const + { + const auto pos = m_event_names.find (event_mask); + if (pos != m_event_names.end()) + return pos->second.c_str(); + return nullptr; + } + + bool + EventTypeHasListeners (uint32_t event_type); + + bool + RemoveListener (lldb_private::Listener *listener, uint32_t event_mask = UINT32_MAX); + + bool + RemoveListener (const lldb::ListenerSP &listener_sp, uint32_t event_mask = UINT32_MAX); + + bool + HijackBroadcaster (const lldb::ListenerSP &listener_sp, uint32_t event_mask = UINT32_MAX); + + bool + IsHijackedForEvent (uint32_t event_mask); + + void + RestoreBroadcaster (); + + protected: + void + PrivateBroadcastEvent (lldb::EventSP &event_sp, bool unique); + + const char * + GetHijackingListenerName(); + + //------------------------------------------------------------------ + // + //------------------------------------------------------------------ + typedef std::list< std::pair<lldb::ListenerWP,uint32_t> > collection; + typedef std::map<uint32_t, std::string> event_names_map; + + void + ListenerIterator (std::function <bool (const lldb::ListenerSP &listener_sp, uint32_t &event_mask)> const &callback); + + + Broadcaster &m_broadcaster; ///< The broadcsater that this implements + event_names_map m_event_names; ///< Optionally define event names for readability and logging for each event bit + collection m_listeners; ///< A list of Listener / event_mask pairs that are listening to this broadcaster. + std::recursive_mutex m_listeners_mutex; ///< A mutex that protects \a m_listeners. + std::vector<lldb::ListenerSP> m_hijacking_listeners; // A simple mechanism to intercept events from a broadcaster + std::vector<uint32_t> m_hijacking_masks; // At some point we may want to have a stack or Listener + // collections, but for now this is just for private hijacking. + + private: + //------------------------------------------------------------------ + // For Broadcaster only + //------------------------------------------------------------------ + DISALLOW_COPY_AND_ASSIGN (BroadcasterImpl); + }; + + typedef std::shared_ptr<BroadcasterImpl> BroadcasterImplSP; + typedef std::weak_ptr<BroadcasterImpl> BroadcasterImplWP; + + BroadcasterImplSP + GetBroadcasterImpl() + { + return m_broadcaster_sp; + } + + const char * + GetHijackingListenerName() + { + return m_broadcaster_sp->GetHijackingListenerName(); + } //------------------------------------------------------------------ // Classes that inherit from Broadcaster can see and modify these //------------------------------------------------------------------ - typedef std::vector< std::pair<Listener*,uint32_t> > collection; - typedef std::map<uint32_t, std::string> event_names_map; - // Prefix the name of our member variables with "m_broadcaster_" - // since this is a class that gets subclassed. - const ConstString m_broadcaster_name; ///< The name of this broadcaster object. - event_names_map m_event_names; ///< Optionally define event names for readability and logging for each event bit - collection m_listeners; ///< A list of Listener / event_mask pairs that are listening to this broadcaster. - Mutex m_listeners_mutex; ///< A mutex that protects \a m_listeners. - std::vector<Listener *> m_hijacking_listeners; // A simple mechanism to intercept events from a broadcaster - std::vector<uint32_t> m_hijacking_masks; // At some point we may want to have a stack or Listener - // collections, but for now this is just for private hijacking. - BroadcasterManager *m_manager; + private: //------------------------------------------------------------------ // For Broadcaster only //------------------------------------------------------------------ + BroadcasterImplSP m_broadcaster_sp; + lldb::BroadcasterManagerSP m_manager_sp; + const ConstString m_broadcaster_name; ///< The name of this broadcaster object. + DISALLOW_COPY_AND_ASSIGN (Broadcaster); }; } // namespace lldb_private -#endif // liblldb_Broadcaster_h_ +#endif // liblldb_Broadcaster_h_ diff --git a/include/lldb/Core/Communication.h b/include/lldb/Core/Communication.h index d29aaca9c2ea9..8913f1631a8bc 100644 --- a/include/lldb/Core/Communication.h +++ b/include/lldb/Core/Communication.h @@ -13,6 +13,7 @@ // C Includes // C++ Includes #include <atomic> +#include <mutex> #include <string> // Other libraries and framework includes @@ -21,7 +22,6 @@ #include "lldb/Core/Broadcaster.h" #include "lldb/Core/Error.h" #include "lldb/Host/HostThread.h" -#include "lldb/Host/Mutex.h" #include "lldb/lldb-private.h" namespace lldb_private { @@ -358,10 +358,10 @@ protected: HostThread m_read_thread; ///< The read thread handle in case we need to cancel the thread. std::atomic<bool> m_read_thread_enabled; std::atomic<bool> m_read_thread_did_exit; - std::string m_bytes; ///< A buffer to cache bytes read in the ReadThread function. - Mutex m_bytes_mutex; ///< A mutex to protect multi-threaded access to the cached bytes. - Mutex m_write_mutex; ///< Don't let multiple threads write at the same time... - Mutex m_synchronize_mutex; + std::string m_bytes; ///< A buffer to cache bytes read in the ReadThread function. + std::recursive_mutex m_bytes_mutex; ///< A mutex to protect multi-threaded access to the cached bytes. + std::mutex m_write_mutex; ///< Don't let multiple threads write at the same time... + std::mutex m_synchronize_mutex; ReadThreadBytesReceived m_callback; void *m_callback_baton; bool m_close_on_eof; diff --git a/include/lldb/Core/ConstString.h b/include/lldb/Core/ConstString.h index 6e234da0a5957..c678168790a88 100644 --- a/include/lldb/Core/ConstString.h +++ b/include/lldb/Core/ConstString.h @@ -291,12 +291,37 @@ public: } //------------------------------------------------------------------ + /// Equal to operator + /// + /// Returns true if this string is equal to the string in \a rhs. + /// If case sensitive equality is tested, this operation is very + /// fast as it results in a pointer comparison since all strings + /// are in a uniqued in a global string pool. + /// + /// @param[in] rhs + /// The Left Hand Side const ConstString object reference. + /// + /// @param[in] rhs + /// The Right Hand Side const ConstString object reference. + /// + /// @param[in] case_sensitive + /// Case sensitivity. If true, case sensitive equality + /// will be tested, otherwise character case will be ignored + /// + /// @return + /// @li \b true if this object is equal to \a rhs. + /// @li \b false if this object is not equal to \a rhs. + //------------------------------------------------------------------ + static bool + Equals(const ConstString &lhs, const ConstString &rhs, const bool case_sensitive = true); + + //------------------------------------------------------------------ /// Compare two string objects. /// /// Compares the C string values contained in \a lhs and \a rhs and /// returns an integer result. /// - /// NOTE: only call this function when you want a true string + /// NOTE: only call this function when you want a true string /// comparison. If you want string equality use the, use the == /// operator as it is much more efficient. Also if you want string /// inequality, use the != operator for the same reasons. @@ -307,13 +332,17 @@ public: /// @param[in] rhs /// The Right Hand Side const ConstString object reference. /// + /// @param[in] case_sensitive + /// Case sensitivity of compare. If true, case sensitive compare + /// will be performed, otherwise character case will be ignored + /// /// @return /// @li -1 if lhs < rhs /// @li 0 if lhs == rhs /// @li 1 if lhs > rhs //------------------------------------------------------------------ static int - Compare (const ConstString& lhs, const ConstString& rhs); + Compare(const ConstString &lhs, const ConstString &rhs, const bool case_sensitive = true); //------------------------------------------------------------------ /// Dump the object description to a stream. diff --git a/include/lldb/Core/DataExtractor.h b/include/lldb/Core/DataExtractor.h index d5cb5e8ba4bc3..51ecade2d3749 100644 --- a/include/lldb/Core/DataExtractor.h +++ b/include/lldb/Core/DataExtractor.h @@ -763,8 +763,10 @@ public: /// /// @param[in] bitfield_bit_offset /// The bit offset of the bitfield value in the extracted - /// integer (the number of bits to shift the integer to the - /// right). + /// integer. For little-endian data, this is the offset of + /// the LSB of the bitfield from the LSB of the integer. + /// For big-endian data, this is the offset of the MSB of the + /// bitfield from the MSB of the integer. /// /// @return /// The unsigned bitfield integer value that was extracted, or @@ -805,8 +807,10 @@ public: /// /// @param[in] bitfield_bit_offset /// The bit offset of the bitfield value in the extracted - /// integer (the number of bits to shift the integer to the - /// right). + /// integer. For little-endian data, this is the offset of + /// the LSB of the bitfield from the LSB of the integer. + /// For big-endian data, this is the offset of the MSB of the + /// bitfield from the MSB of the integer. /// /// @return /// The signed bitfield integer value that was extracted, or diff --git a/include/lldb/Core/Debugger.h b/include/lldb/Core/Debugger.h index 4ca648ca296eb..7a969457eef6a 100644 --- a/include/lldb/Core/Debugger.h +++ b/include/lldb/Core/Debugger.h @@ -16,6 +16,7 @@ // C++ Includes #include <memory> #include <map> +#include <mutex> #include <vector> // Other libraries and framework includes @@ -53,8 +54,7 @@ namespace lldb_private { class Debugger : public std::enable_shared_from_this<Debugger>, public UserID, - public Properties, - public BroadcasterManager + public Properties { friend class SourceManager; // For GetSourceFileCache. @@ -159,10 +159,10 @@ public: return *m_command_interpreter_ap; } - Listener & + lldb::ListenerSP GetListener () { - return m_listener; + return m_listener_sp; } // This returns the Debugger's scratch source manager. It won't be able to look up files in debug @@ -392,6 +392,12 @@ public: Target *GetSelectedOrDummyTarget(bool prefer_dummy = false); Target *GetDummyTarget(); + lldb::BroadcasterManagerSP + GetBroadcasterManager() + { + return m_broadcaster_manager_sp; + } + protected: friend class CommandInterpreter; friend class REPL; @@ -446,15 +452,20 @@ protected: void InstanceInitialize (); - + lldb::StreamFileSP m_input_file_sp; lldb::StreamFileSP m_output_file_sp; lldb::StreamFileSP m_error_file_sp; + + lldb::BroadcasterManagerSP m_broadcaster_manager_sp; // The debugger acts as a broadcaster manager of last resort. + // It needs to get constructed before the target_list or any other + // member that might want to broadcast through the debugger. + TerminalState m_terminal_state; TargetList m_target_list; PlatformList m_platform_list; - Listener m_listener; + lldb::ListenerSP m_listener_sp; std::unique_ptr<SourceManager> m_source_manager_ap; // This is a scratch source manager that we return if we have no targets. SourceManager::SourceFileCache m_source_file_cache; // All the source managers for targets created in this debugger used this shared // source file cache. @@ -472,6 +483,7 @@ protected: HostThread m_io_handler_thread; Broadcaster m_sync_broadcaster; lldb::ListenerSP m_forward_listener_sp; + std::once_flag m_clear_once; //---------------------------------------------------------------------- // Events for m_sync_broadcaster diff --git a/include/lldb/Core/EmulateInstruction.h b/include/lldb/Core/EmulateInstruction.h index c5e60022fc963..36fff43bf6bcc 100644 --- a/include/lldb/Core/EmulateInstruction.h +++ b/include/lldb/Core/EmulateInstruction.h @@ -384,6 +384,11 @@ public: const RegisterInfo *reg_info, const RegisterValue ®_value); + // Type to represent the condition of an instruction. The UINT32 value is reserved for the + // unconditional case and all other value can be used in an architecture dependent way. + typedef uint32_t InstructionCondition; + static const InstructionCondition UnconditionalCondition = UINT32_MAX; + EmulateInstruction (const ArchSpec &arch); ~EmulateInstruction() override = default; @@ -403,8 +408,8 @@ public: virtual bool EvaluateInstruction (uint32_t evaluate_options) = 0; - virtual bool - IsInstructionConditional() { return false; } + virtual InstructionCondition + GetInstructionCondition() { return UnconditionalCondition; } virtual bool TestEmulation (Stream *out_stream, ArchSpec &arch, OptionValueDictionary *test_data) = 0; diff --git a/include/lldb/Core/Event.h b/include/lldb/Core/Event.h index e8867c0e7e772..1ae0fc83b27e2 100644 --- a/include/lldb/Core/Event.h +++ b/include/lldb/Core/Event.h @@ -20,6 +20,7 @@ #include "lldb/lldb-private.h" #include "lldb/Core/ConstString.h" #include "lldb/Host/Predicate.h" +#include "lldb/Core/Broadcaster.h" namespace lldb_private { @@ -113,20 +114,66 @@ private: DISALLOW_COPY_AND_ASSIGN (EventDataBytes); }; +class EventDataReceipt : public EventData +{ +public: + EventDataReceipt() : + EventData(), + m_predicate(false) + { + } + + ~EventDataReceipt() override + { + } + + static const ConstString & + GetFlavorString () + { + static ConstString g_flavor("Process::ProcessEventData"); + return g_flavor; + } + + const ConstString & + GetFlavor () const override + { + return GetFlavorString(); + } + + bool + WaitForEventReceived (const TimeValue *abstime = nullptr, bool *timed_out = nullptr) + { + return m_predicate.WaitForValueEqualTo(true, abstime, timed_out); + } + +private: + Predicate<bool> m_predicate; + + void + DoOnRemoval (Event *event_ptr) override + { + m_predicate.SetValue(true, eBroadcastAlways); + } +}; + //---------------------------------------------------------------------- // lldb::Event //---------------------------------------------------------------------- class Event { - friend class Broadcaster; friend class Listener; friend class EventData; + friend class Broadcaster::BroadcasterImpl; public: Event(Broadcaster *broadcaster, uint32_t event_type, EventData *data = nullptr); + Event(Broadcaster *broadcaster, uint32_t event_type, const lldb::EventDataSP &event_data_sp); + Event(uint32_t event_type, EventData *data = nullptr); + Event(uint32_t event_type, const lldb::EventDataSP &event_data_sp); + ~Event (); void @@ -135,19 +182,19 @@ public: EventData * GetData () { - return m_data_ap.get(); + return m_data_sp.get(); } const EventData * GetData () const { - return m_data_ap.get(); + return m_data_sp.get(); } void SetData (EventData *new_data) { - m_data_ap.reset (new_data); + m_data_sp.reset (new_data); } uint32_t @@ -165,19 +212,27 @@ public: Broadcaster * GetBroadcaster () const { - return m_broadcaster; + Broadcaster::BroadcasterImplSP broadcaster_impl_sp = m_broadcaster_wp.lock(); + if (broadcaster_impl_sp) + return broadcaster_impl_sp->GetBroadcaster(); + else + return nullptr; } bool BroadcasterIs (Broadcaster *broadcaster) { - return broadcaster == m_broadcaster; + Broadcaster::BroadcasterImplSP broadcaster_impl_sp = m_broadcaster_wp.lock(); + if (broadcaster_impl_sp) + return broadcaster_impl_sp->GetBroadcaster() == broadcaster; + else + return false; } void Clear() { - m_data_ap.reset(); + m_data_sp.reset(); } private: @@ -194,12 +249,12 @@ private: void SetBroadcaster (Broadcaster *broadcaster) { - m_broadcaster = broadcaster; + m_broadcaster_wp = broadcaster->GetBroadcasterImpl(); } - Broadcaster * m_broadcaster; // The broadcaster that sent this event - uint32_t m_type; // The bit describing this event - std::unique_ptr<EventData> m_data_ap; // User specific data for this event + Broadcaster::BroadcasterImplWP m_broadcaster_wp; // The broadcaster that sent this event + uint32_t m_type; // The bit describing this event + lldb::EventDataSP m_data_sp; // User specific data for this event DISALLOW_COPY_AND_ASSIGN (Event); diff --git a/include/lldb/Core/History.h b/include/lldb/Core/History.h index fbb7bd8b0c1a7..164d1bfb651b5 100644 --- a/include/lldb/Core/History.h +++ b/include/lldb/Core/History.h @@ -14,13 +14,13 @@ #include <stdint.h> // C++ Includes +#include <mutex> #include <stack> #include <string> // Other libraries and framework includes // Project includes #include "lldb/lldb-public.h" -#include "lldb/Host/Mutex.h" namespace lldb_private { @@ -34,11 +34,7 @@ class HistorySource public: typedef const void * HistoryEvent; - HistorySource () : - m_mutex (Mutex::eMutexTypeRecursive), - m_events () - { - } + HistorySource() : m_mutex(), m_events() {} virtual ~HistorySource() @@ -50,20 +46,20 @@ public: // onto the end of the history stack. virtual HistoryEvent - CreateHistoryEvent () = 0; - + CreateHistoryEvent () = 0; + virtual void DeleteHistoryEvent (HistoryEvent event) = 0; - + virtual void DumpHistoryEvent (Stream &strm, HistoryEvent event) = 0; virtual size_t GetHistoryEventCount() = 0; - + virtual HistoryEvent GetHistoryEventAtIndex (uint32_t idx) = 0; - + virtual HistoryEvent GetCurrentHistoryEvent () = 0; @@ -71,16 +67,16 @@ public: virtual int CompareHistoryEvents (const HistoryEvent lhs, const HistoryEvent rhs) = 0; - + virtual bool IsCurrentHistoryEvent (const HistoryEvent event) = 0; private: typedef std::stack<HistoryEvent> collection; - Mutex m_mutex; + std::recursive_mutex m_mutex; collection m_events; - + DISALLOW_COPY_AND_ASSIGN (HistorySource); }; diff --git a/include/lldb/Core/IOHandler.h b/include/lldb/Core/IOHandler.h index 3eba1c3cc9d83..1844df3651586 100644 --- a/include/lldb/Core/IOHandler.h +++ b/include/lldb/Core/IOHandler.h @@ -15,6 +15,7 @@ // C++ Includes #include <memory> +#include <mutex> #include <string> #include <vector> @@ -28,7 +29,6 @@ #include "lldb/Core/Stream.h" #include "lldb/Core/StringList.h" #include "lldb/Core/ValueObjectList.h" -#include "lldb/Host/Mutex.h" #include "lldb/Host/Predicate.h" namespace curses @@ -709,75 +709,70 @@ namespace lldb_private { class IOHandlerStack { public: - IOHandlerStack () : - m_stack(), - m_mutex(Mutex::eMutexTypeRecursive), - m_top (nullptr) - { - } - + IOHandlerStack() : m_stack(), m_mutex(), m_top(nullptr) {} + ~IOHandlerStack() = default; - + size_t - GetSize () const + GetSize() const { - Mutex::Locker locker (m_mutex); + std::lock_guard<std::recursive_mutex> guard(m_mutex); return m_stack.size(); } - + void - Push (const lldb::IOHandlerSP& sp) + Push(const lldb::IOHandlerSP &sp) { if (sp) { - Mutex::Locker locker (m_mutex); - sp->SetPopped (false); - m_stack.push_back (sp); + std::lock_guard<std::recursive_mutex> guard(m_mutex); + sp->SetPopped(false); + m_stack.push_back(sp); // Set m_top the non-locking IsTop() call m_top = sp.get(); } } - + bool - IsEmpty () const + IsEmpty() const { - Mutex::Locker locker (m_mutex); + std::lock_guard<std::recursive_mutex> guard(m_mutex); return m_stack.empty(); } - + lldb::IOHandlerSP - Top () + Top() { lldb::IOHandlerSP sp; { - Mutex::Locker locker (m_mutex); + std::lock_guard<std::recursive_mutex> guard(m_mutex); if (!m_stack.empty()) sp = m_stack.back(); } return sp; } - + void - Pop () + Pop() { - Mutex::Locker locker (m_mutex); + std::lock_guard<std::recursive_mutex> guard(m_mutex); if (!m_stack.empty()) { - lldb::IOHandlerSP sp (m_stack.back()); + lldb::IOHandlerSP sp(m_stack.back()); m_stack.pop_back(); - sp->SetPopped (true); + sp->SetPopped(true); } // Set m_top the non-locking IsTop() call m_top = (m_stack.empty() ? nullptr : m_stack.back().get()); } - Mutex & + std::recursive_mutex & GetMutex() { return m_mutex; } - + bool IsTop (const lldb::IOHandlerSP &io_handler_sp) const { @@ -785,13 +780,12 @@ namespace lldb_private { } bool - CheckTopIOHandlerTypes (IOHandler::Type top_type, IOHandler::Type second_top_type) + CheckTopIOHandlerTypes(IOHandler::Type top_type, IOHandler::Type second_top_type) { - Mutex::Locker locker (m_mutex); + std::lock_guard<std::recursive_mutex> guard(m_mutex); const size_t num_io_handlers = m_stack.size(); - return (num_io_handlers >= 2 && - m_stack[num_io_handlers-1]->GetType() == top_type && - m_stack[num_io_handlers-2]->GetType() == second_top_type); + return (num_io_handlers >= 2 && m_stack[num_io_handlers - 1]->GetType() == top_type && + m_stack[num_io_handlers - 2]->GetType() == second_top_type); } ConstString @@ -818,9 +812,9 @@ namespace lldb_private { protected: typedef std::vector<lldb::IOHandlerSP> collection; collection m_stack; - mutable Mutex m_mutex; + mutable std::recursive_mutex m_mutex; IOHandler *m_top; - + private: DISALLOW_COPY_AND_ASSIGN (IOHandlerStack); }; diff --git a/include/lldb/Core/Listener.h b/include/lldb/Core/Listener.h index b11c1644507b0..1057cf35c6db6 100644 --- a/include/lldb/Core/Listener.h +++ b/include/lldb/Core/Listener.h @@ -14,18 +14,21 @@ // C++ Includes #include <list> #include <map> +#include <mutex> #include <string> #include <vector> // Other libraries and framework includes // Project includes #include "lldb/lldb-private.h" -#include "lldb/Host/Predicate.h" +#include "lldb/Core/Broadcaster.h" +#include "lldb/Host/Condition.h" #include "lldb/Core/Event.h" namespace lldb_private { -class Listener +class Listener : + public std::enable_shared_from_this<Listener> { public: typedef bool (*HandleBroadcastCallback) (lldb::EventSP &event_sp, void *baton); @@ -36,8 +39,16 @@ public: //------------------------------------------------------------------ // Constructors and Destructors //------------------------------------------------------------------ + // + // Listeners have to be constructed into shared pointers - at least if you want them to listen to + // Broadcasters, +protected: Listener (const char *name); +public: + static lldb::ListenerSP + MakeListener(const char *name); + ~Listener (); void @@ -53,11 +64,11 @@ public: } uint32_t - StartListeningForEventSpec (BroadcasterManager &manager, + StartListeningForEventSpec (lldb::BroadcasterManagerSP manager_sp, const BroadcastEventSpec &event_spec); bool - StopListeningForEventSpec (BroadcasterManager &manager, + StopListeningForEventSpec (lldb::BroadcasterManagerSP manager_sp, const BroadcastEventSpec &event_spec); uint32_t @@ -133,12 +144,15 @@ private: void *callback_user_data; }; - typedef std::multimap<Broadcaster*, BroadcasterInfo> broadcaster_collection; + typedef std::multimap<Broadcaster::BroadcasterImplWP, + BroadcasterInfo, + std::owner_less<Broadcaster::BroadcasterImplWP>> broadcaster_collection; typedef std::list<lldb::EventSP> event_collection; - typedef std::vector<BroadcasterManager *> broadcaster_manager_collection; + typedef std::vector<lldb::BroadcasterManagerWP> broadcaster_manager_collection; bool - FindNextEventInternal(Broadcaster *broadcaster, // nullptr for any broadcaster + FindNextEventInternal(Mutex::Locker& lock, + Broadcaster *broadcaster, // nullptr for any broadcaster const ConstString *sources, // nullptr for any event uint32_t num_sources, uint32_t event_type_mask, @@ -162,17 +176,17 @@ private: std::string m_name; broadcaster_collection m_broadcasters; - Mutex m_broadcasters_mutex; // Protects m_broadcasters + std::recursive_mutex m_broadcasters_mutex; // Protects m_broadcasters event_collection m_events; Mutex m_events_mutex; // Protects m_broadcasters and m_events - Predicate<bool> m_cond_wait; + Condition m_events_condition; broadcaster_manager_collection m_broadcaster_managers; void BroadcasterWillDestruct (Broadcaster *); void - BroadcasterManagerWillDestruct (BroadcasterManager *manager); + BroadcasterManagerWillDestruct (lldb::BroadcasterManagerSP manager_sp); // broadcaster_collection::iterator diff --git a/include/lldb/Core/Logging.h b/include/lldb/Core/Logging.h index ca04c84b21a63..da8c0d8f5bb69 100644 --- a/include/lldb/Core/Logging.h +++ b/include/lldb/Core/Logging.h @@ -49,6 +49,7 @@ #define LIBLLDB_LOG_JIT_LOADER (1u << 27) #define LIBLLDB_LOG_LANGUAGE (1u << 28) #define LIBLLDB_LOG_DATAFORMATTERS (1u << 29) +#define LIBLLDB_LOG_DEMANGLE (1u << 30) #define LIBLLDB_LOG_ALL (UINT32_MAX) #define LIBLLDB_LOG_DEFAULT (LIBLLDB_LOG_PROCESS |\ LIBLLDB_LOG_THREAD |\ diff --git a/include/lldb/Core/MappedHash.h b/include/lldb/Core/MappedHash.h index 5a52ab2b8b2d5..b7cf3b02e01e8 100644 --- a/include/lldb/Core/MappedHash.h +++ b/include/lldb/Core/MappedHash.h @@ -47,6 +47,9 @@ public: static uint32_t HashString (uint32_t hash_function, const char *s) { + if (!s) + return 0; + switch (hash_function) { case MappedHash::eHashFunctionDJB: @@ -434,6 +437,9 @@ public: bool Find (const char *name, Pair &pair) const { + if (!name || !name[0]) + return false; + if (IsValid ()) { const uint32_t bucket_count = m_header.bucket_count; diff --git a/include/lldb/Core/Module.h b/include/lldb/Core/Module.h index 35b182aa9801f..46fa330fb19c5 100644 --- a/include/lldb/Core/Module.h +++ b/include/lldb/Core/Module.h @@ -13,6 +13,7 @@ // C Includes // C++ Includes #include <atomic> +#include <mutex> #include <string> #include <vector> @@ -22,11 +23,11 @@ #include "lldb/Core/ArchSpec.h" #include "lldb/Core/UUID.h" #include "lldb/Host/FileSpec.h" -#include "lldb/Host/Mutex.h" #include "lldb/Host/TimeValue.h" #include "lldb/Symbol/SymbolContextScope.h" #include "lldb/Symbol/TypeSystem.h" #include "lldb/Target/PathMappingList.h" +#include "llvm/ADT/DenseSet.h" namespace lldb_private { @@ -67,7 +68,7 @@ public: static Module * GetAllocatedModuleAtIndex (size_t idx); - static Mutex * + static std::recursive_mutex & GetAllocationModuleCollectionMutex(); //------------------------------------------------------------------ @@ -498,6 +499,7 @@ public: const ConstString &type_name, bool exact_match, size_t max_matches, + llvm::DenseSet<lldb_private::SymbolFile *> &searched_symbol_files, TypeList& types); lldb::TypeSP @@ -984,8 +986,8 @@ public: // SymbolVendor, SymbolFile and ObjectFile member objects should // lock the module mutex to avoid deadlocks. //------------------------------------------------------------------ - Mutex & - GetMutex () const + std::recursive_mutex & + GetMutex() const { return m_mutex; } @@ -1046,65 +1048,96 @@ public: bool RemapSourceFile (const char *path, std::string &new_path) const; - //------------------------------------------------------------------ - /// Prepare to do a function name lookup. - /// - /// Looking up functions by name can be a tricky thing. LLDB requires - /// that accelerator tables contain full names for functions as well - /// as function basenames which include functions, class methods and - /// class functions. When the user requests that an action use a - /// function by name, we are sometimes asked to automatically figure - /// out what a name could possibly map to. A user might request a - /// breakpoint be set on "count". If no options are supplied to limit - /// the scope of where to search for count, we will by default match - /// any function names named "count", all class and instance methods - /// named "count" (no matter what the namespace or contained context) - /// and any selectors named "count". If a user specifies "a::b" we - /// will search for the basename "b", and then prune the results that - /// don't match "a::b" (note that "c::a::b" and "d::e::a::b" will - /// match a query of "a::b". - /// - /// @param[in] name - /// The user supplied name to use in the lookup - /// - /// @param[in] name_type_mask - /// The mask of bits from lldb::FunctionNameType enumerations - /// that tell us what kind of name we are looking for. - /// - /// @param[out] language - /// If known, the language to use for determining the - /// lookup_name_type_mask. - /// - /// @param[out] lookup_name - /// The actual name that will be used when calling - /// SymbolVendor::FindFunctions() or Symtab::FindFunctionSymbols() - /// - /// @param[out] lookup_name_type_mask - /// The actual name mask that should be used in the calls to - /// SymbolVendor::FindFunctions() or Symtab::FindFunctionSymbols() - /// - /// @param[out] match_name_after_lookup - /// A boolean that indicates if we need to iterate through any - /// match results obtained from SymbolVendor::FindFunctions() or - /// Symtab::FindFunctionSymbols() to see if the name contains - /// \a name. For example if \a name is "a::b", this function will - /// return a \a lookup_name of "b", with \a match_name_after_lookup - /// set to true to indicate any matches will need to be checked - /// to make sure they contain \a name. - //------------------------------------------------------------------ - static void - PrepareForFunctionNameLookup (const ConstString &name, - uint32_t name_type_mask, - lldb::LanguageType language, - ConstString &lookup_name, - uint32_t &lookup_name_type_mask, - bool &match_name_after_lookup); + //---------------------------------------------------------------------- + /// @class LookupInfo Module.h "lldb/Core/Module.h" + /// @brief A class that encapsulates name lookup information. + /// + /// Users can type a wide variety of partial names when setting + /// breakpoints by name or when looking for functions by name. + /// SymbolVendor and SymbolFile objects are only required to implement + /// name lookup for function basenames and for fully mangled names. + /// This means if the user types in a partial name, we must reduce this + /// to a name lookup that will work with all SymbolFile objects. So we + /// might reduce a name lookup to look for a basename, and then prune + /// out any results that don't match. + /// + /// The "m_name" member variable represents the name as it was typed + /// by the user. "m_lookup_name" will be the name we actually search + /// for through the symbol or objects files. Lanaguage is included in + /// case we need to filter results by language at a later date. The + /// "m_name_type_mask" member variable tells us what kinds of names we + /// are looking for and can help us prune out unwanted results. + /// + /// Function lookups are done in Module.cpp, ModuleList.cpp and in + /// BreakpointResolverName.cpp and they all now use this class to do + /// lookups correctly. + //---------------------------------------------------------------------- + class LookupInfo + { + public: + LookupInfo() : + m_name(), + m_lookup_name(), + m_language(lldb::eLanguageTypeUnknown), + m_name_type_mask(0), + m_match_name_after_lookup(false) + { + } + + LookupInfo(const ConstString &name, uint32_t name_type_mask, lldb::LanguageType language); + + const ConstString & + GetName() const + { + return m_name; + } + + void + SetName(const ConstString &name) + { + m_name = name; + } + + const ConstString & + GetLookupName() const + { + return m_lookup_name; + } + + void + SetLookupName(const ConstString &name) + { + m_lookup_name = name; + } + + uint32_t + GetNameTypeMask() const + { + return m_name_type_mask; + } + + void + SetNameTypeMask(uint32_t mask) + { + m_name_type_mask = mask; + } + + void + Prune(SymbolContextList &sc_list, size_t start_idx) const; + + protected: + ConstString m_name; ///< What the user originally typed + ConstString m_lookup_name; ///< The actual name will lookup when calling in the object or symbol file + lldb::LanguageType m_language; ///< Limit matches to only be for this language + uint32_t m_name_type_mask; ///< One or more bits from lldb::FunctionNameType that indicate what kind of names we are looking for + bool m_match_name_after_lookup; ///< If \b true, then demangled names that match will need to contain "m_name" in order to be considered a match + }; protected: //------------------------------------------------------------------ // Member Variables //------------------------------------------------------------------ - mutable Mutex m_mutex; ///< A mutex to keep this object happy in multi-threaded environments. + mutable std::recursive_mutex m_mutex; ///< A mutex to keep this object happy in multi-threaded environments. TimeValue m_mod_time; ///< The modification time for this module when it was created. ArchSpec m_arch; ///< The architecture for this module. UUID m_uuid; ///< Each module is assumed to have a unique identifier to help match it up to debug symbols. @@ -1194,6 +1227,7 @@ private: const CompilerDeclContext *parent_decl_ctx, bool append, size_t max_matches, + llvm::DenseSet<lldb_private::SymbolFile *> &searched_symbol_files, TypeMap& types); DISALLOW_COPY_AND_ASSIGN (Module); diff --git a/include/lldb/Core/ModuleList.h b/include/lldb/Core/ModuleList.h index a0dd43263a2c5..38a91b0bf0ee6 100644 --- a/include/lldb/Core/ModuleList.h +++ b/include/lldb/Core/ModuleList.h @@ -14,13 +14,14 @@ // C++ Includes #include <functional> #include <list> +#include <mutex> #include <vector> // Other libraries and framework includes // Project includes #include "lldb/lldb-private.h" -#include "lldb/Host/Mutex.h" #include "lldb/Utility/Iterable.h" +#include "llvm/ADT/DenseSet.h" namespace lldb_private { @@ -163,13 +164,13 @@ public: void LogUUIDAndPaths (Log *log, const char *prefix_cstr); - - Mutex & - GetMutex () const + + std::recursive_mutex & + GetMutex() const { return m_modules_mutex; } - + size_t GetIndexForModule (const Module *module) const; @@ -450,6 +451,7 @@ public: const ConstString &name, bool name_is_fully_qualified, size_t max_matches, + llvm::DenseSet<SymbolFile *> &searched_symbol_files, TypeList& types) const; bool @@ -591,12 +593,12 @@ protected: // Member variables. //------------------------------------------------------------------ collection m_modules; ///< The collection of modules. - mutable Mutex m_modules_mutex; + mutable std::recursive_mutex m_modules_mutex; Notifier* m_notifier; public: - typedef LockingAdaptedIterable<collection, lldb::ModuleSP, vector_adapter> ModuleIterable; + typedef LockingAdaptedIterable<collection, lldb::ModuleSP, vector_adapter, std::recursive_mutex> ModuleIterable; ModuleIterable Modules() { diff --git a/include/lldb/Core/ModuleSpec.h b/include/lldb/Core/ModuleSpec.h index 95de7f375736a..245cb2365b2e2 100644 --- a/include/lldb/Core/ModuleSpec.h +++ b/include/lldb/Core/ModuleSpec.h @@ -12,6 +12,7 @@ // C Includes // C++ Includes +#include <mutex> #include <vector> // Other libraries and framework includes @@ -20,7 +21,6 @@ #include "lldb/Core/Stream.h" #include "lldb/Core/UUID.h" #include "lldb/Host/FileSpec.h" -#include "lldb/Host/Mutex.h" #include "lldb/Target/PathMappingList.h" namespace lldb_private { @@ -447,30 +447,24 @@ protected: class ModuleSpecList { public: - ModuleSpecList () : - m_specs(), - m_mutex(Mutex::eMutexTypeRecursive) - { - } + ModuleSpecList() : m_specs(), m_mutex() {} - ModuleSpecList (const ModuleSpecList &rhs) : - m_specs(), - m_mutex(Mutex::eMutexTypeRecursive) + ModuleSpecList(const ModuleSpecList &rhs) : m_specs(), m_mutex() { - Mutex::Locker lhs_locker(m_mutex); - Mutex::Locker rhs_locker(rhs.m_mutex); + std::lock_guard<std::recursive_mutex> lhs_guard(m_mutex); + std::lock_guard<std::recursive_mutex> rhs_guard(rhs.m_mutex); m_specs = rhs.m_specs; } ~ModuleSpecList() = default; ModuleSpecList & - operator = (const ModuleSpecList &rhs) + operator=(const ModuleSpecList &rhs) { if (this != &rhs) { - Mutex::Locker lhs_locker(m_mutex); - Mutex::Locker rhs_locker(rhs.m_mutex); + std::lock_guard<std::recursive_mutex> lhs_guard(m_mutex); + std::lock_guard<std::recursive_mutex> rhs_guard(rhs.m_mutex); m_specs = rhs.m_specs; } return *this; @@ -479,29 +473,29 @@ public: size_t GetSize() const { - Mutex::Locker locker(m_mutex); + std::lock_guard<std::recursive_mutex> guard(m_mutex); return m_specs.size(); } void - Clear () + Clear() { - Mutex::Locker locker(m_mutex); + std::lock_guard<std::recursive_mutex> guard(m_mutex); m_specs.clear(); } void - Append (const ModuleSpec &spec) + Append(const ModuleSpec &spec) { - Mutex::Locker locker(m_mutex); - m_specs.push_back (spec); + std::lock_guard<std::recursive_mutex> guard(m_mutex); + m_specs.push_back(spec); } void - Append (const ModuleSpecList &rhs) + Append(const ModuleSpecList &rhs) { - Mutex::Locker lhs_locker(m_mutex); - Mutex::Locker rhs_locker(rhs.m_mutex); + std::lock_guard<std::recursive_mutex> lhs_guard(m_mutex); + std::lock_guard<std::recursive_mutex> rhs_guard(rhs.m_mutex); m_specs.insert(m_specs.end(), rhs.m_specs.begin(), rhs.m_specs.end()); } @@ -514,9 +508,9 @@ public: } bool - GetModuleSpecAtIndex (size_t i, ModuleSpec &module_spec) const + GetModuleSpecAtIndex(size_t i, ModuleSpec &module_spec) const { - Mutex::Locker locker(m_mutex); + std::lock_guard<std::recursive_mutex> guard(m_mutex); if (i < m_specs.size()) { module_spec = m_specs[i]; @@ -527,11 +521,11 @@ public: } bool - FindMatchingModuleSpec (const ModuleSpec &module_spec, ModuleSpec &match_module_spec) const + FindMatchingModuleSpec(const ModuleSpec &module_spec, ModuleSpec &match_module_spec) const { - Mutex::Locker locker(m_mutex); + std::lock_guard<std::recursive_mutex> guard(m_mutex); bool exact_arch_match = true; - for (auto spec: m_specs) + for (auto spec : m_specs) { if (spec.Matches(module_spec, exact_arch_match)) { @@ -539,12 +533,12 @@ public: return true; } } - + // If there was an architecture, retry with a compatible arch if (module_spec.GetArchitecturePtr()) { exact_arch_match = false; - for (auto spec: m_specs) + for (auto spec : m_specs) { if (spec.Matches(module_spec, exact_arch_match)) { @@ -556,41 +550,41 @@ public: match_module_spec.Clear(); return false; } - + size_t - FindMatchingModuleSpecs (const ModuleSpec &module_spec, ModuleSpecList &matching_list) const + FindMatchingModuleSpecs(const ModuleSpec &module_spec, ModuleSpecList &matching_list) const { - Mutex::Locker locker(m_mutex); + std::lock_guard<std::recursive_mutex> guard(m_mutex); bool exact_arch_match = true; const size_t initial_match_count = matching_list.GetSize(); - for (auto spec: m_specs) + for (auto spec : m_specs) { if (spec.Matches(module_spec, exact_arch_match)) - matching_list.Append (spec); + matching_list.Append(spec); } - + // If there was an architecture, retry with a compatible arch if no matches were found if (module_spec.GetArchitecturePtr() && (initial_match_count == matching_list.GetSize())) { exact_arch_match = false; - for (auto spec: m_specs) + for (auto spec : m_specs) { if (spec.Matches(module_spec, exact_arch_match)) - matching_list.Append (spec); + matching_list.Append(spec); } } return matching_list.GetSize() - initial_match_count; } void - Dump (Stream &strm) + Dump(Stream &strm) { - Mutex::Locker locker(m_mutex); + std::lock_guard<std::recursive_mutex> guard(m_mutex); uint32_t idx = 0; - for (auto spec: m_specs) + for (auto spec : m_specs) { strm.Printf("[%u] ", idx); - spec.Dump (strm); + spec.Dump(strm); strm.EOL(); ++idx; } @@ -599,7 +593,7 @@ public: protected: typedef std::vector<ModuleSpec> collection; ///< The module collection type. collection m_specs; ///< The collection of modules. - mutable Mutex m_mutex; + mutable std::recursive_mutex m_mutex; }; } // namespace lldb_private diff --git a/include/lldb/Core/RangeMap.h b/include/lldb/Core/RangeMap.h index 28d3083979d61..eb68859aed3fd 100644 --- a/include/lldb/Core/RangeMap.h +++ b/include/lldb/Core/RangeMap.h @@ -202,7 +202,13 @@ namespace lldb_private { { m_entries.push_back (entry); } - + + void + Append (B base, S size) + { + m_entries.emplace_back(base, size); + } + bool RemoveEntrtAtIndex (uint32_t idx) { @@ -471,7 +477,13 @@ namespace lldb_private { { m_entries.push_back (entry); } - + + void + Append (B base, S size) + { + m_entries.emplace_back(base, size); + } + bool RemoveEntrtAtIndex (uint32_t idx) { @@ -1123,7 +1135,7 @@ namespace lldb_private { // Calculate the byte size of ranges with zero byte sizes by finding // the next entry with a base address > the current base address void - CalculateSizesOfZeroByteSizeRanges () + CalculateSizesOfZeroByteSizeRanges (S full_size = 0) { #ifdef ASSERT_RANGEMAP_ARE_SORTED assert (IsSorted()); @@ -1148,6 +1160,8 @@ namespace lldb_private { break; } } + if (next == end && full_size > curr_base) + pos->SetByteSize (full_size - curr_base); } } } @@ -1181,7 +1195,13 @@ namespace lldb_private { { return ((i < m_entries.size()) ? &m_entries[i] : nullptr); } - + + Entry * + GetMutableEntryAtIndex (size_t i) + { + return ((i < m_entries.size()) ? &m_entries[i] : nullptr); + } + // Clients must ensure that "i" is a valid index prior to calling this function const Entry & GetEntryRef (size_t i) const @@ -1305,6 +1325,42 @@ namespace lldb_private { return nullptr; } + const Entry* + FindEntryStartsAt (B addr) const + { +#ifdef ASSERT_RANGEMAP_ARE_SORTED + assert (IsSorted()); +#endif + if (!m_entries.empty()) + { + auto begin = m_entries.begin(), end = m_entries.end(); + auto pos = std::lower_bound (begin, end, Entry(addr, 1), BaseLessThan); + if (pos != end && pos->base == addr) + return &(*pos); + } + return nullptr; + } + + const Entry * + FindEntryThatContainsOrFollows(B addr) const + { +#ifdef ASSERT_RANGEMAP_ARE_SORTED + assert(IsSorted()); +#endif + if (!m_entries.empty()) + { + typename Collection::const_iterator end = m_entries.end(); + typename Collection::const_iterator pos = + std::lower_bound(m_entries.begin(), end, addr, [](const Entry &lhs, B rhs_base) -> bool { + return lhs.GetRangeEnd() <= rhs_base; + }); + + if (pos != end) + return &(*pos); + } + return nullptr; + } + Entry * Back() { diff --git a/include/lldb/Core/RegisterValue.h b/include/lldb/Core/RegisterValue.h index 030b849212c49..0626b5f2c857b 100644 --- a/include/lldb/Core/RegisterValue.h +++ b/include/lldb/Core/RegisterValue.h @@ -354,9 +354,6 @@ namespace lldb_private { lldb::Format format, uint32_t reg_name_right_align_at = 0) const; - void * - GetBytes (); - const void * GetBytes () const; diff --git a/include/lldb/Core/Scalar.h b/include/lldb/Core/Scalar.h index a476cd3bd8676..be2176e2b50eb 100644 --- a/include/lldb/Core/Scalar.h +++ b/include/lldb/Core/Scalar.h @@ -16,6 +16,8 @@ #define NUM_OF_WORDS_INT128 2 #define BITWIDTH_INT128 128 +#define NUM_OF_WORDS_INT256 4 +#define BITWIDTH_INT256 256 namespace lldb_private { @@ -41,7 +43,9 @@ public: e_double, e_long_double, e_uint128, - e_sint128 + e_sint128, + e_uint256, + e_sint256 }; //------------------------------------------------------------------ @@ -91,6 +95,12 @@ public: else m_type = e_uint128; break; + case 256: + if(m_integer.isSignedIntN(BITWIDTH_INT256)) + m_type = e_sint256; + else + m_type = e_uint256; + break; } } Scalar(const Scalar& rhs); @@ -110,7 +120,7 @@ public: bool ClearBit(uint32_t bit); - void * + const void * GetBytes() const; size_t @@ -152,6 +162,9 @@ public: bool MakeSigned (); + bool + MakeUnsigned (); + static const char * GetValueTypeAsCString (Scalar::Type value_type); @@ -221,9 +234,6 @@ public: Scalar::Type GetType() const { return m_type; } - void - SetType(const RegisterInfo*); - //---------------------------------------------------------------------- // Returns a casted value of the current contained data without // modifying the current value. FAIL_VALUE will be returned if the type @@ -232,22 +242,10 @@ public: int SInt(int fail_value = 0) const; - // Return the raw unsigned integer without any casting or conversion - unsigned int - RawUInt () const; - - // Return the raw unsigned long without any casting or conversion - unsigned long - RawULong () const; - - // Return the raw unsigned long long without any casting or conversion - unsigned long long - RawULongLong () const; - unsigned char UChar(unsigned char fail_value = 0) const; - char + signed char SChar(char fail_value = 0) const; unsigned short @@ -277,6 +275,12 @@ public: llvm::APInt UInt128(const llvm::APInt& fail_value) const; + llvm::APInt + SInt256(llvm::APInt& fail_value) const; + + llvm::APInt + UInt256(const llvm::APInt& fail_value) const; + float Float(float fail_value = 0.0f) const; @@ -286,9 +290,6 @@ public: long double LongDouble(long double fail_value = 0.0) const; - uint64_t - GetRawBits64 (uint64_t fail_value) const; - Error SetValueFromCString (const char *s, lldb::Encoding encoding, size_t byte_size); diff --git a/include/lldb/Core/SearchFilter.h b/include/lldb/Core/SearchFilter.h index 3d5e1fb39b439..5c76fb5aad30b 100644 --- a/include/lldb/Core/SearchFilter.h +++ b/include/lldb/Core/SearchFilter.h @@ -94,7 +94,6 @@ public: class SearchFilter { public: - //------------------------------------------------------------------ /// The basic constructor takes a Target, which gives the space to search. /// @@ -108,7 +107,7 @@ public: virtual ~SearchFilter (); - const SearchFilter& + SearchFilter& operator=(const SearchFilter& rhs); //------------------------------------------------------------------ @@ -294,7 +293,6 @@ class SearchFilterByModule : public SearchFilter { public: - //------------------------------------------------------------------ /// The basic constructor takes a Target, which gives the space to search, /// and the module to restrict the search to. @@ -312,7 +310,7 @@ public: ~SearchFilterByModule() override; - const SearchFilterByModule& + SearchFilterByModule& operator=(const SearchFilterByModule& rhs); bool @@ -354,7 +352,6 @@ class SearchFilterByModuleList : public SearchFilter { public: - //------------------------------------------------------------------ /// The basic constructor takes a Target, which gives the space to search, /// and the module list to restrict the search to. @@ -372,7 +369,7 @@ public: ~SearchFilterByModuleList() override; - const SearchFilterByModuleList& + SearchFilterByModuleList& operator=(const SearchFilterByModuleList& rhs); bool @@ -414,7 +411,6 @@ class SearchFilterByModuleListAndCU : public SearchFilterByModuleList { public: - //------------------------------------------------------------------ /// The basic constructor takes a Target, which gives the space to search, /// and the module list to restrict the search to. @@ -433,7 +429,7 @@ public: ~SearchFilterByModuleListAndCU() override; - const SearchFilterByModuleListAndCU& + SearchFilterByModuleListAndCU& operator=(const SearchFilterByModuleListAndCU& rhs); bool diff --git a/include/lldb/Core/Section.h b/include/lldb/Core/Section.h index 8c92f1ba667ef..0837e326f97b1 100644 --- a/include/lldb/Core/Section.h +++ b/include/lldb/Core/Section.h @@ -273,7 +273,19 @@ public: { m_thread_specific = b; } - + + //------------------------------------------------------------------ + /// Get the permissions as OR'ed bits from lldb::Permissions + //------------------------------------------------------------------ + uint32_t + GetPermissions() const; + + //------------------------------------------------------------------ + /// Set the permissions using bits OR'ed from lldb::Permissions + //------------------------------------------------------------------ + void + SetPermissions(uint32_t permissions); + ObjectFile * GetObjectFile () { @@ -356,12 +368,15 @@ protected: lldb::offset_t m_file_size; // Object file size (can be smaller than m_byte_size for zero filled sections...) uint32_t m_log2align; // log_2(align) of the section (i.e. section has to be aligned to 2^m_log2align) SectionList m_children; // Child sections - bool m_fake:1, // If true, then this section only can contain the address if one of its + bool m_fake : 1, // If true, then this section only can contain the address if one of its // children contains an address. This allows for gaps between the children // that are contained in the address range for this section, but do not produce // hits unless the children contain the address. - m_encrypted:1, // Set to true if the contents are encrypted - m_thread_specific:1;// This section is thread specific + m_encrypted : 1, // Set to true if the contents are encrypted + m_thread_specific : 1, // This section is thread specific + m_readable : 1, // If this section has read permissions + m_writable : 1, // If this section has write permissions + m_executable : 1; // If this section has executable permissions uint32_t m_target_byte_size; // Some architectures have non-8-bit byte size. This is specified as // as a multiple number of a host bytes private: diff --git a/include/lldb/Core/StreamCallback.h b/include/lldb/Core/StreamCallback.h index e5a9da7512bb8..9e91eb94a74c3 100644 --- a/include/lldb/Core/StreamCallback.h +++ b/include/lldb/Core/StreamCallback.h @@ -10,11 +10,11 @@ #ifndef liblldb_StreamCallback_h_ #define liblldb_StreamCallback_h_ +#include <mutex> #include <string> #include "lldb/Core/Stream.h" #include "lldb/Core/StreamString.h" -#include "lldb/Host/Mutex.h" namespace lldb_private { @@ -37,8 +37,8 @@ private: lldb::LogOutputCallback m_callback; void *m_baton; collection m_accumulated_data; - Mutex m_collection_mutex; - + std::mutex m_collection_mutex; + StreamString &FindStreamForThread(lldb::tid_t cur_tid); }; diff --git a/include/lldb/Core/StreamTee.h b/include/lldb/Core/StreamTee.h index 7ab619b3bb79e..6059e0e1f8e9d 100644 --- a/include/lldb/Core/StreamTee.h +++ b/include/lldb/Core/StreamTee.h @@ -12,50 +12,37 @@ #include <limits.h> +#include <mutex> + #include "lldb/Core/Stream.h" -#include "lldb/Host/Mutex.h" namespace lldb_private { class StreamTee : public Stream { public: - StreamTee () : - Stream (), - m_streams_mutex (Mutex::eMutexTypeRecursive), - m_streams () - { - } + StreamTee() : Stream(), m_streams_mutex(), m_streams() {} - StreamTee (lldb::StreamSP &stream_sp): - Stream (), - m_streams_mutex (Mutex::eMutexTypeRecursive), - m_streams () + StreamTee(lldb::StreamSP &stream_sp) : Stream(), m_streams_mutex(), m_streams() { // No need to lock mutex during construction if (stream_sp) - m_streams.push_back (stream_sp); + m_streams.push_back(stream_sp); } - - StreamTee (lldb::StreamSP &stream_sp, lldb::StreamSP &stream_2_sp) : - Stream (), - m_streams_mutex (Mutex::eMutexTypeRecursive), - m_streams () + StreamTee(lldb::StreamSP &stream_sp, lldb::StreamSP &stream_2_sp) : Stream(), m_streams_mutex(), m_streams() { // No need to lock mutex during construction if (stream_sp) - m_streams.push_back (stream_sp); + m_streams.push_back(stream_sp); if (stream_2_sp) - m_streams.push_back (stream_2_sp); + m_streams.push_back(stream_2_sp); } - - StreamTee (const StreamTee &rhs) : - Stream (rhs), - m_streams_mutex (Mutex::eMutexTypeRecursive), - m_streams() // Don't copy until we lock down "rhs" + + StreamTee(const StreamTee &rhs) : Stream(rhs), m_streams_mutex(), m_streams() { - Mutex::Locker locker (rhs.m_streams_mutex); + // Don't copy until we lock down "rhs" + std::lock_guard<std::recursive_mutex> guard(rhs.m_streams_mutex); m_streams = rhs.m_streams; } @@ -64,21 +51,22 @@ public: } StreamTee & - operator = (const StreamTee &rhs) + operator=(const StreamTee &rhs) { - if (this != &rhs) { + if (this != &rhs) + { Stream::operator=(rhs); - Mutex::Locker lhs_locker (m_streams_mutex); - Mutex::Locker rhs_locker (rhs.m_streams_mutex); - m_streams = rhs.m_streams; + std::lock_guard<std::recursive_mutex> lhs_locker(m_streams_mutex); + std::lock_guard<std::recursive_mutex> rhs_locker(rhs.m_streams_mutex); + m_streams = rhs.m_streams; } return *this; } void - Flush () override + Flush() override { - Mutex::Locker locker (m_streams_mutex); + std::lock_guard<std::recursive_mutex> guard(m_streams_mutex); collection::iterator pos, end; for (pos = m_streams.begin(), end = m_streams.end(); pos != end; ++pos) { @@ -88,17 +76,17 @@ public: // to valid values. Stream *strm = pos->get(); if (strm) - strm->Flush (); + strm->Flush(); } } size_t - Write (const void *s, size_t length) override + Write(const void *s, size_t length) override { - Mutex::Locker locker (m_streams_mutex); + std::lock_guard<std::recursive_mutex> guard(m_streams_mutex); if (m_streams.empty()) return 0; - + size_t min_bytes_written = SIZE_MAX; collection::iterator pos, end; for (pos = m_streams.begin(), end = m_streams.end(); pos != end; ++pos) @@ -110,7 +98,7 @@ public: Stream *strm = pos->get(); if (strm) { - const size_t bytes_written = strm->Write (s, length); + const size_t bytes_written = strm->Write(s, length); if (min_bytes_written > bytes_written) min_bytes_written = bytes_written; } @@ -121,39 +109,39 @@ public: } size_t - AppendStream (const lldb::StreamSP &stream_sp) + AppendStream(const lldb::StreamSP &stream_sp) { size_t new_idx = m_streams.size(); - Mutex::Locker locker (m_streams_mutex); - m_streams.push_back (stream_sp); + std::lock_guard<std::recursive_mutex> guard(m_streams_mutex); + m_streams.push_back(stream_sp); return new_idx; } size_t - GetNumStreams () const + GetNumStreams() const { size_t result = 0; { - Mutex::Locker locker (m_streams_mutex); + std::lock_guard<std::recursive_mutex> guard(m_streams_mutex); result = m_streams.size(); } return result; } lldb::StreamSP - GetStreamAtIndex (uint32_t idx) + GetStreamAtIndex(uint32_t idx) { lldb::StreamSP stream_sp; - Mutex::Locker locker (m_streams_mutex); + std::lock_guard<std::recursive_mutex> guard(m_streams_mutex); if (idx < m_streams.size()) stream_sp = m_streams[idx]; return stream_sp; } void - SetStreamAtIndex (uint32_t idx, const lldb::StreamSP& stream_sp) + SetStreamAtIndex(uint32_t idx, const lldb::StreamSP &stream_sp) { - Mutex::Locker locker (m_streams_mutex); + std::lock_guard<std::recursive_mutex> guard(m_streams_mutex); // Resize our stream vector as necessary to fit as many streams // as needed. This also allows this class to be used with hard // coded indexes that can be used contain many streams, not all @@ -162,10 +150,10 @@ public: m_streams.resize(idx + 1); m_streams[idx] = stream_sp; } - + protected: typedef std::vector<lldb::StreamSP> collection; - mutable Mutex m_streams_mutex; + mutable std::recursive_mutex m_streams_mutex; collection m_streams; }; diff --git a/include/lldb/Core/ThreadSafeSTLMap.h b/include/lldb/Core/ThreadSafeSTLMap.h index 4235edc92ade7..4a885ff1a480f 100644 --- a/include/lldb/Core/ThreadSafeSTLMap.h +++ b/include/lldb/Core/ThreadSafeSTLMap.h @@ -13,11 +13,11 @@ // C Includes // C++ Includes #include <map> +#include <mutex> // Other libraries and framework includes // Project includes #include "lldb/lldb-defines.h" -#include "lldb/Host/Mutex.h" namespace lldb_private { @@ -31,11 +31,7 @@ public: //------------------------------------------------------------------ // Constructors and Destructors //------------------------------------------------------------------ - ThreadSafeSTLMap() : - m_collection (), - m_mutex (Mutex::eMutexTypeRecursive) - { - } + ThreadSafeSTLMap() : m_collection(), m_mutex() {} ~ThreadSafeSTLMap() { @@ -44,22 +40,22 @@ public: bool IsEmpty() const { - Mutex::Locker locker(m_mutex); + std::lock_guard<std::recursive_mutex> guard(m_mutex); return m_collection.empty(); } - + void Clear() { - Mutex::Locker locker(m_mutex); + std::lock_guard<std::recursive_mutex> guard(m_mutex); return m_collection.clear(); } size_t - Erase (const _Key& key) + Erase(const _Key &key) { - Mutex::Locker locker(m_mutex); - return EraseNoLock (key); + std::lock_guard<std::recursive_mutex> guard(m_mutex); + return EraseNoLock(key); } size_t @@ -69,10 +65,10 @@ public: } bool - GetValueForKey (const _Key& key, _Tp &value) const + GetValueForKey(const _Key &key, _Tp &value) const { - Mutex::Locker locker(m_mutex); - return GetValueForKeyNoLock (key, value); + std::lock_guard<std::recursive_mutex> guard(m_mutex); + return GetValueForKeyNoLock(key, value); } // Call this if you have already manually locked the mutex using the @@ -90,10 +86,10 @@ public: } bool - GetFirstKeyForValue (const _Tp &value, _Key& key) const + GetFirstKeyForValue(const _Tp &value, _Key &key) const { - Mutex::Locker locker(m_mutex); - return GetFirstKeyForValueNoLock (value, key); + std::lock_guard<std::recursive_mutex> guard(m_mutex); + return GetFirstKeyForValueNoLock(value, key); } bool @@ -112,13 +108,10 @@ public: } bool - LowerBound (const _Key& key, - _Key& match_key, - _Tp &match_value, - bool decrement_if_not_equal) const + LowerBound(const _Key &key, _Key &match_key, _Tp &match_value, bool decrement_if_not_equal) const { - Mutex::Locker locker(m_mutex); - return LowerBoundNoLock (key, match_key, match_value, decrement_if_not_equal); + std::lock_guard<std::recursive_mutex> guard(m_mutex); + return LowerBoundNoLock(key, match_key, match_value, decrement_if_not_equal); } bool @@ -149,10 +142,10 @@ public: } void - SetValueForKey (const _Key& key, const _Tp &value) + SetValueForKey(const _Key &key, const _Tp &value) { - Mutex::Locker locker(m_mutex); - SetValueForKeyNoLock (key, value); + std::lock_guard<std::recursive_mutex> guard(m_mutex); + SetValueForKeyNoLock(key, value); } // Call this if you have already manually locked the mutex using the @@ -163,15 +156,15 @@ public: m_collection[key] = value; } - Mutex & - GetMutex () + std::recursive_mutex & + GetMutex() { return m_mutex; } private: collection m_collection; - mutable Mutex m_mutex; + mutable std::recursive_mutex m_mutex; //------------------------------------------------------------------ // For ThreadSafeSTLMap only diff --git a/include/lldb/Core/ThreadSafeSTLVector.h b/include/lldb/Core/ThreadSafeSTLVector.h new file mode 100644 index 0000000000000..dd90d49afcb88 --- /dev/null +++ b/include/lldb/Core/ThreadSafeSTLVector.h @@ -0,0 +1,99 @@ +//===-- ThreadSafeSTLVector.h ------------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef liblldb_ThreadSafeSTLVector_h_ +#define liblldb_ThreadSafeSTLVector_h_ + +// C Includes +// C++ Includes +#include <vector> +#include <mutex> + +// Other libraries and framework includes +// Project includes +#include "lldb/lldb-defines.h" + +namespace lldb_private { + + template <typename _Object> + class ThreadSafeSTLVector + { + public: + typedef std::vector<_Object> collection; + typedef typename collection::iterator iterator; + typedef typename collection::const_iterator const_iterator; + //------------------------------------------------------------------ + // Constructors and Destructors + //------------------------------------------------------------------ + ThreadSafeSTLVector() : m_collection(), m_mutex() {} + + ~ThreadSafeSTLVector() = default; + + bool + IsEmpty() const + { + std::lock_guard<std::recursive_mutex> guard(m_mutex); + return m_collection.empty(); + } + + void + Clear() + { + std::lock_guard<std::recursive_mutex> guard(m_mutex); + return m_collection.clear(); + } + + size_t + GetCount() + { + std::lock_guard<std::recursive_mutex> guard(m_mutex); + return m_collection.size(); + } + + void + AppendObject (_Object& object) + { + std::lock_guard<std::recursive_mutex> guard(m_mutex); + m_collection.push_back(object); + } + + _Object + GetObject (size_t index) + { + std::lock_guard<std::recursive_mutex> guard(m_mutex); + return m_collection.at(index); + } + + void + SetObject (size_t index, const _Object& object) + { + std::lock_guard<std::recursive_mutex> guard(m_mutex); + m_collection.at(index) = object; + } + + std::recursive_mutex & + GetMutex() + { + return m_mutex; + } + + private: + collection m_collection; + mutable std::recursive_mutex m_mutex; + + //------------------------------------------------------------------ + // For ThreadSafeSTLVector only + //------------------------------------------------------------------ + DISALLOW_COPY_AND_ASSIGN (ThreadSafeSTLVector); + }; + + +} // namespace lldb_private + +#endif // liblldb_ThreadSafeSTLVector_h_ diff --git a/include/lldb/Core/ThreadSafeValue.h b/include/lldb/Core/ThreadSafeValue.h index 42a5a5c6725a4..cad36a0c1637a 100644 --- a/include/lldb/Core/ThreadSafeValue.h +++ b/include/lldb/Core/ThreadSafeValue.h @@ -11,10 +11,12 @@ #define liblldb_ThreadSafeValue_h_ // C Includes + // C++ Includes +#include <mutex> + // Other libraries and framework includes // Project includes -#include "lldb/Host/Mutex.h" namespace lldb_private { @@ -25,28 +27,20 @@ public: //------------------------------------------------------------------ // Constructors and Destructors //------------------------------------------------------------------ - ThreadSafeValue() : - m_value (), - m_mutex (Mutex::eMutexTypeRecursive) - { - } + ThreadSafeValue() : m_value(), m_mutex() {} - ThreadSafeValue(const T& value) : - m_value (value), - m_mutex (Mutex::eMutexTypeRecursive) - { - } + ThreadSafeValue(const T &value) : m_value(value), m_mutex() {} ~ThreadSafeValue() { } T - GetValue () const + GetValue() const { T value; { - Mutex::Locker locker(m_mutex); + std::lock_guard<std::recursive_mutex> guard(m_mutex); value = m_value; } return value; @@ -61,9 +55,9 @@ public: } void - SetValue (const T& value) + SetValue(const T &value) { - Mutex::Locker locker(m_mutex); + std::lock_guard<std::recursive_mutex> guard(m_mutex); m_value = value; } @@ -75,15 +69,15 @@ public: m_value = value; } - Mutex & - GetMutex () + std::recursive_mutex & + GetMutex() { return m_mutex; } private: T m_value; - mutable Mutex m_mutex; + mutable std::recursive_mutex m_mutex; //------------------------------------------------------------------ // For ThreadSafeValue only diff --git a/include/lldb/Core/Timer.h b/include/lldb/Core/Timer.h index ffaeba6fce9b7..4d89700644cc3 100644 --- a/include/lldb/Core/Timer.h +++ b/include/lldb/Core/Timer.h @@ -50,9 +50,6 @@ public: //-------------------------------------------------------------- ~Timer(); - static void - Initialize (); - void Dump (); @@ -89,8 +86,6 @@ protected: static std::atomic<bool> g_quiet; static std::atomic<unsigned> g_display_depth; - static std::mutex g_file_mutex; - static FILE* g_file; private: Timer(); diff --git a/include/lldb/Core/UserSettingsController.h b/include/lldb/Core/UserSettingsController.h index 7e72b89ad8e6d..6c395c81c37b7 100644 --- a/include/lldb/Core/UserSettingsController.h +++ b/include/lldb/Core/UserSettingsController.h @@ -24,7 +24,6 @@ #include "lldb/Core/StringList.h" #include "lldb/Core/Stream.h" #include "lldb/Core/StreamString.h" -#include "lldb/Host/Mutex.h" #include "lldb/Interpreter/OptionValue.h" namespace lldb_private { @@ -89,6 +88,20 @@ public: lldb::OptionValuePropertiesSP GetSubProperty (const ExecutionContext *exe_ctx, const ConstString &name); + + // We sometimes need to introduce a setting to enable experimental features, + // but then we don't want the setting for these to cause errors when the setting + // goes away. Add a sub-topic of the settings using this experimental name, and + // two things will happen. One is that settings that don't find the name will not + // be treated as errors. Also, if you decide to keep the settings just move them into + // the containing properties, and we will auto-forward the experimental settings to the + // real one. + static const char * + GetExperimentalSettingsName(); + + static bool + IsSettingExperimental(const char *setting); + protected: lldb::OptionValuePropertiesSP m_collection_sp; }; diff --git a/include/lldb/Core/Value.h b/include/lldb/Core/Value.h index a6d934afd294e..7539b550dc420 100644 --- a/include/lldb/Core/Value.h +++ b/include/lldb/Core/Value.h @@ -169,9 +169,8 @@ public: m_context = p; if (m_context_type == eContextTypeRegisterInfo) { RegisterInfo *reg_info = GetRegisterInfo(); - if (reg_info->encoding == lldb::eEncodingVector) - SetValueType(eValueTypeVector); - else + if (reg_info->encoding == lldb::eEncodingVector && + m_vector.byte_order != lldb::eByteOrderInvalid) SetValueType(eValueTypeScalar); } } diff --git a/include/lldb/Core/ValueObject.h b/include/lldb/Core/ValueObject.h index c066cc7d3661d..bef158feb39db 100644 --- a/include/lldb/Core/ValueObject.h +++ b/include/lldb/Core/ValueObject.h @@ -699,10 +699,16 @@ public: GetSyntheticExpressionPathChild(const char* expression, bool can_create); virtual lldb::ValueObjectSP - GetSyntheticChildAtOffset(uint32_t offset, const CompilerType& type, bool can_create); + GetSyntheticChildAtOffset(uint32_t offset, + const CompilerType& type, + bool can_create, + ConstString name_const_str = ConstString()); virtual lldb::ValueObjectSP - GetSyntheticBase (uint32_t offset, const CompilerType& type, bool can_create); + GetSyntheticBase (uint32_t offset, + const CompilerType& type, + bool can_create, + ConstString name_const_str = ConstString()); virtual lldb::ValueObjectSP GetDynamicValue (lldb::DynamicValueType valueType); @@ -787,10 +793,10 @@ public: return false; } - bool + virtual bool IsSyntheticChildrenGenerated (); - void + virtual void SetSyntheticChildrenGenerated (bool b); virtual SymbolContextScope * @@ -1028,35 +1034,32 @@ protected: class ChildrenManager { public: - ChildrenManager() : - m_mutex(Mutex::eMutexTypeRecursive), - m_children(), - m_children_count(0) - {} - + ChildrenManager() : m_mutex(), m_children(), m_children_count(0) {} + bool - HasChildAtIndex (size_t idx) + HasChildAtIndex(size_t idx) { - Mutex::Locker locker(m_mutex); + std::lock_guard<std::recursive_mutex> guard(m_mutex); return (m_children.find(idx) != m_children.end()); } - - ValueObject* - GetChildAtIndex (size_t idx) + + ValueObject * + GetChildAtIndex(size_t idx) { - Mutex::Locker locker(m_mutex); + std::lock_guard<std::recursive_mutex> guard(m_mutex); const auto iter = m_children.find(idx); return ((iter == m_children.end()) ? nullptr : iter->second); } - + void - SetChildAtIndex (size_t idx, ValueObject* valobj) + SetChildAtIndex(size_t idx, ValueObject *valobj) { - ChildrenPair pair(idx,valobj); // we do not need to be mutex-protected to make a pair - Mutex::Locker locker(m_mutex); + // we do not need to be mutex-protected to make a pair + ChildrenPair pair(idx, valobj); + std::lock_guard<std::recursive_mutex> guard(m_mutex); m_children.insert(pair); } - + void SetChildrenCount (size_t count) { @@ -1068,20 +1071,20 @@ protected: { return m_children_count; } - + void Clear(size_t new_count = 0) { - Mutex::Locker locker(m_mutex); + std::lock_guard<std::recursive_mutex> guard(m_mutex); m_children_count = new_count; m_children.clear(); } - + private: typedef std::map<size_t, ValueObject*> ChildrenMap; typedef ChildrenMap::iterator ChildrenIterator; typedef ChildrenMap::value_type ChildrenPair; - Mutex m_mutex; + std::recursive_mutex m_mutex; ChildrenMap m_children; size_t m_children_count; }; diff --git a/include/lldb/Core/ValueObjectConstResult.h b/include/lldb/Core/ValueObjectConstResult.h index f63ee83284df7..892df8c62cc5e 100644 --- a/include/lldb/Core/ValueObjectConstResult.h +++ b/include/lldb/Core/ValueObjectConstResult.h @@ -97,7 +97,10 @@ public: CreateChildAtIndex(size_t idx, bool synthetic_array_member, int32_t synthetic_index) override; lldb::ValueObjectSP - GetSyntheticChildAtOffset(uint32_t offset, const CompilerType& type, bool can_create) override; + GetSyntheticChildAtOffset(uint32_t offset, + const CompilerType& type, + bool can_create, + ConstString name_const_str = ConstString()) override; lldb::ValueObjectSP AddressOf(Error &error) override; diff --git a/include/lldb/Core/ValueObjectConstResultCast.h b/include/lldb/Core/ValueObjectConstResultCast.h index 395820dad6c7a..84dd79213d02c 100644 --- a/include/lldb/Core/ValueObjectConstResultCast.h +++ b/include/lldb/Core/ValueObjectConstResultCast.h @@ -47,7 +47,8 @@ public: lldb::ValueObjectSP GetSyntheticChildAtOffset(uint32_t offset, const CompilerType& type, - bool can_create) override; + bool can_create, + ConstString name_const_str = ConstString()) override; lldb::ValueObjectSP AddressOf (Error &error) override; diff --git a/include/lldb/Core/ValueObjectConstResultChild.h b/include/lldb/Core/ValueObjectConstResultChild.h index 356d175a64aeb..e4a238a96c8f5 100644 --- a/include/lldb/Core/ValueObjectConstResultChild.h +++ b/include/lldb/Core/ValueObjectConstResultChild.h @@ -53,7 +53,10 @@ public: } lldb::ValueObjectSP - GetSyntheticChildAtOffset(uint32_t offset, const CompilerType& type, bool can_create) override; + GetSyntheticChildAtOffset(uint32_t offset, + const CompilerType& type, + bool can_create, + ConstString name_const_str = ConstString()) override; lldb::ValueObjectSP AddressOf (Error &error) override; diff --git a/include/lldb/Core/ValueObjectConstResultImpl.h b/include/lldb/Core/ValueObjectConstResultImpl.h index 36b82f00a2408..848a221c3d055 100644 --- a/include/lldb/Core/ValueObjectConstResultImpl.h +++ b/include/lldb/Core/ValueObjectConstResultImpl.h @@ -39,7 +39,10 @@ public: CreateChildAtIndex (size_t idx, bool synthetic_array_member, int32_t synthetic_index); lldb::ValueObjectSP - GetSyntheticChildAtOffset (uint32_t offset, const CompilerType& type, bool can_create); + GetSyntheticChildAtOffset (uint32_t offset, + const CompilerType& type, + bool can_create, + ConstString name_const_str = ConstString()); lldb::ValueObjectSP AddressOf (Error &error); diff --git a/include/lldb/Core/ValueObjectDynamicValue.h b/include/lldb/Core/ValueObjectDynamicValue.h index 80f37f1047654..8a045c3b0db1a 100644 --- a/include/lldb/Core/ValueObjectDynamicValue.h +++ b/include/lldb/Core/ValueObjectDynamicValue.h @@ -117,6 +117,12 @@ public: void SetPreferredDisplayLanguage (lldb::LanguageType); + + bool + IsSyntheticChildrenGenerated () override; + + void + SetSyntheticChildrenGenerated (bool b) override; bool GetDeclaration(Declaration &decl) override; diff --git a/include/lldb/Core/ValueObjectSyntheticFilter.h b/include/lldb/Core/ValueObjectSyntheticFilter.h index 05bc3781a3cc6..38d9f7b5ade13 100644 --- a/include/lldb/Core/ValueObjectSyntheticFilter.h +++ b/include/lldb/Core/ValueObjectSyntheticFilter.h @@ -17,6 +17,7 @@ // Other libraries and framework includes // Project includes #include "lldb/Core/ThreadSafeSTLMap.h" +#include "lldb/Core/ThreadSafeSTLVector.h" #include "lldb/Core/ValueObject.h" namespace lldb_private { @@ -147,6 +148,12 @@ public: SetPreferredDisplayLanguage (lldb::LanguageType); bool + IsSyntheticChildrenGenerated () override; + + void + SetSyntheticChildrenGenerated (bool b) override; + + bool GetDeclaration(Declaration &decl) override; uint64_t @@ -177,6 +184,7 @@ protected: typedef ThreadSafeSTLMap<uint32_t, ValueObject*> ByIndexMap; typedef ThreadSafeSTLMap<const char*, uint32_t> NameToIndexMap; + typedef ThreadSafeSTLVector<lldb::ValueObjectSP> SyntheticChildrenCache; typedef ByIndexMap::iterator ByIndexIterator; typedef NameToIndexMap::iterator NameToIndexIterator; @@ -184,6 +192,7 @@ protected: ByIndexMap m_children_byindex; NameToIndexMap m_name_toindex; uint32_t m_synthetic_children_count; // FIXME use the ValueObject's ChildrenManager instead of a special purpose solution + SyntheticChildrenCache m_synthetic_children_cache; ConstString m_parent_type_name; |