diff options
Diffstat (limited to 'include')
182 files changed, 3644 insertions, 1381 deletions
diff --git a/include/Makefile b/include/Makefile deleted file mode 100644 index 02acdce10271..000000000000 --- a/include/Makefile +++ /dev/null @@ -1,13 +0,0 @@ -##===- include/Makefile ------------------------------------*- Makefile -*-===## -# -# The LLVM Compiler Infrastructure -# -# This file is distributed under the University of Illinois Open Source -# License. See LICENSE.TXT for details. -# -##===----------------------------------------------------------------------===## - -LLDB_LEVEL := .. -DIRS := lldb - -include $(LLDB_LEVEL)/Makefile diff --git a/include/lldb/API/LLDB.h b/include/lldb/API/LLDB.h index eed10d08c6cc..b6278160dbc0 100644 --- a/include/lldb/API/LLDB.h +++ b/include/lldb/API/LLDB.h @@ -43,6 +43,8 @@ #include "lldb/API/SBLaunchInfo.h" #include "lldb/API/SBLineEntry.h" #include "lldb/API/SBListener.h" +#include "lldb/API/SBMemoryRegionInfo.h" +#include "lldb/API/SBMemoryRegionInfoList.h" #include "lldb/API/SBModule.h" #include "lldb/API/SBModuleSpec.h" #include "lldb/API/SBPlatform.h" diff --git a/include/lldb/API/SBCommandReturnObject.h b/include/lldb/API/SBCommandReturnObject.h index b45eb9c14c04..2b7cce5ded59 100644 --- a/include/lldb/API/SBCommandReturnObject.h +++ b/include/lldb/API/SBCommandReturnObject.h @@ -83,7 +83,9 @@ public: bool GetDescription (lldb::SBStream &description); - + + // deprecated, these two functions do not take + // ownership of file handle void SetImmediateOutputFile (FILE *fh); @@ -91,6 +93,12 @@ public: SetImmediateErrorFile (FILE *fh); void + SetImmediateOutputFile (FILE *fh, bool transfer_ownership); + + void + SetImmediateErrorFile (FILE *fh, bool transfer_ownership); + + void PutCString(const char* string, int len = -1); size_t diff --git a/include/lldb/API/SBDefines.h b/include/lldb/API/SBDefines.h index d81bba5a2e23..4a95903ec92c 100644 --- a/include/lldb/API/SBDefines.h +++ b/include/lldb/API/SBDefines.h @@ -59,6 +59,8 @@ class LLDB_API SBLanguageRuntime; class LLDB_API SBLaunchInfo; class LLDB_API SBLineEntry; class LLDB_API SBListener; +class LLDB_API SBMemoryRegionInfo; +class LLDB_API SBMemoryRegionInfoList; class LLDB_API SBModule; class LLDB_API SBModuleSpec; class LLDB_API SBModuleSpecList; diff --git a/include/lldb/API/SBExpressionOptions.h b/include/lldb/API/SBExpressionOptions.h index ed2f9187b3e0..051ed7220ac8 100644 --- a/include/lldb/API/SBExpressionOptions.h +++ b/include/lldb/API/SBExpressionOptions.h @@ -110,6 +110,19 @@ public: void SetPrefix (const char *prefix); + + void + SetAutoApplyFixIts(bool b = true); + + bool + GetAutoApplyFixIts(); + + bool + GetTopLevel (); + + void + SetTopLevel (bool b = true); + protected: diff --git a/include/lldb/API/SBFileSpec.h b/include/lldb/API/SBFileSpec.h index d6f38f5b2d74..2f9d6bab89f3 100644 --- a/include/lldb/API/SBFileSpec.h +++ b/include/lldb/API/SBFileSpec.h @@ -60,6 +60,9 @@ public: bool GetDescription (lldb::SBStream &description) const; + void + AppendPathComponent (const char *file_or_directory); + private: friend class SBAttachInfo; friend class SBBlock; diff --git a/include/lldb/API/SBHostOS.h b/include/lldb/API/SBHostOS.h index d9bc97365632..a3675856a136 100644 --- a/include/lldb/API/SBHostOS.h +++ b/include/lldb/API/SBHostOS.h @@ -28,6 +28,9 @@ public: static lldb::SBFileSpec GetLLDBPath (lldb::PathType path_type); + static lldb::SBFileSpec + GetUserHomeDirectory (); + static void ThreadCreated (const char *name); diff --git a/include/lldb/API/SBInstruction.h b/include/lldb/API/SBInstruction.h index 2bacc2b97746..cb0b2a32a829 100644 --- a/include/lldb/API/SBInstruction.h +++ b/include/lldb/API/SBInstruction.h @@ -18,6 +18,8 @@ // There's a lot to be fixed here, but need to wait for underlying insn implementation // to be revised & settle down first. +class InstructionImpl; + namespace lldb { class LLDB_API SBInstruction @@ -81,14 +83,17 @@ public: protected: friend class SBInstructionList; - SBInstruction (const lldb::InstructionSP &inst_sp); + SBInstruction(const lldb::DisassemblerSP &disasm_sp, const lldb::InstructionSP &inst_sp); void - SetOpaque (const lldb::InstructionSP &inst_sp); + SetOpaque(const lldb::DisassemblerSP &disasm_sp, const lldb::InstructionSP& inst_sp); + + lldb::InstructionSP + GetOpaque(); private: - lldb::InstructionSP m_opaque_sp; + std::shared_ptr<InstructionImpl> m_opaque_sp; }; diff --git a/include/lldb/API/SBLaunchInfo.h b/include/lldb/API/SBLaunchInfo.h index 68c0f386acde..38d598aec456 100644 --- a/include/lldb/API/SBLaunchInfo.h +++ b/include/lldb/API/SBLaunchInfo.h @@ -145,7 +145,7 @@ public: GetShellExpandArguments (); void - SetShellExpandArguments (bool glob); + SetShellExpandArguments (bool expand); uint32_t GetResumeCount (); diff --git a/include/lldb/API/SBListener.h b/include/lldb/API/SBListener.h index 924f8109f638..e74d318ea118 100644 --- a/include/lldb/API/SBListener.h +++ b/include/lldb/API/SBListener.h @@ -106,8 +106,6 @@ protected: friend class SBLaunchInfo; friend class SBTarget; - SBListener (lldb_private::Listener &listener); - SBListener (const lldb::ListenerSP &listener_sp); lldb::ListenerSP @@ -124,20 +122,11 @@ private: lldb_private::Listener * get() const; - lldb_private::Listener & - ref() const; - - lldb_private::Listener & - operator *(); - - const lldb_private::Listener & - operator *() const; - void - reset(lldb_private::Listener *listener, bool transfer_ownership); + reset(lldb::ListenerSP listener_sp); lldb::ListenerSP m_opaque_sp; - lldb_private::Listener *m_opaque_ptr; + lldb_private::Listener *m_unused_ptr; }; } // namespace lldb diff --git a/include/lldb/API/SBMemoryRegionInfo.h b/include/lldb/API/SBMemoryRegionInfo.h new file mode 100644 index 000000000000..fadd0760891b --- /dev/null +++ b/include/lldb/API/SBMemoryRegionInfo.h @@ -0,0 +1,117 @@ +//===-- SBMemoryRegionInfo.h ------------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef LLDB_SBMemoryRegionInfo_h_ +#define LLDB_SBMemoryRegionInfo_h_ + +#include "lldb/API/SBDefines.h" +#include "lldb/API/SBData.h" + +namespace lldb { + +class LLDB_API SBMemoryRegionInfo +{ +public: + + SBMemoryRegionInfo (); + + SBMemoryRegionInfo (const lldb::SBMemoryRegionInfo &rhs); + + ~SBMemoryRegionInfo (); + + const lldb::SBMemoryRegionInfo & + operator = (const lldb::SBMemoryRegionInfo &rhs); + + void + Clear(); + + //------------------------------------------------------------------ + /// Get the base address of this memory range. + /// + /// @return + /// The base address of this memory range. + //------------------------------------------------------------------ + lldb::addr_t + GetRegionBase (); + + //------------------------------------------------------------------ + /// Get the end address of this memory range. + /// + /// @return + /// The base address of this memory range. + //------------------------------------------------------------------ + lldb::addr_t + GetRegionEnd (); + + //------------------------------------------------------------------ + /// Check if this memory address is marked readable to the process. + /// + /// @return + /// true if this memory address is marked readable + //------------------------------------------------------------------ + bool + IsReadable (); + + //------------------------------------------------------------------ + /// Check if this memory address is marked writable to the process. + /// + /// @return + /// true if this memory address is marked writable + //------------------------------------------------------------------ + bool + IsWritable (); + + //------------------------------------------------------------------ + /// Check if this memory address is marked executable to the process. + /// + /// @return + /// true if this memory address is marked executable + //------------------------------------------------------------------ + bool + IsExecutable (); + + //------------------------------------------------------------------ + /// Check if this memory address is mapped into the process address + /// space. + /// + /// @return + /// true if this memory address is in the process address space. + //------------------------------------------------------------------ + bool + IsMapped (); + + bool + operator == (const lldb::SBMemoryRegionInfo &rhs) const; + + bool + operator != (const lldb::SBMemoryRegionInfo &rhs) const; + + bool + GetDescription (lldb::SBStream &description); + +private: + + friend class SBProcess; + friend class SBMemoryRegionInfoList; + + lldb_private::MemoryRegionInfo & + ref(); + + const lldb_private::MemoryRegionInfo & + ref() const; + + SBMemoryRegionInfo (const lldb_private::MemoryRegionInfo *lldb_object_ptr); + + lldb::MemoryRegionInfoUP m_opaque_ap; +}; + + +} // namespace lldb + +#endif // LLDB_SBMemoryRegionInfo_h_ diff --git a/include/lldb/API/SBMemoryRegionInfoList.h b/include/lldb/API/SBMemoryRegionInfoList.h new file mode 100644 index 000000000000..7723820897d8 --- /dev/null +++ b/include/lldb/API/SBMemoryRegionInfoList.h @@ -0,0 +1,63 @@ +//===-- SBMemoryRegionInfoList.h --------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef LLDB_SBMemoryRegionInfoList_h_ +#define LLDB_SBMemoryRegionInfoList_h_ + +#include "lldb/API/SBDefines.h" + +class MemoryRegionInfoListImpl; + +namespace lldb { + +class LLDB_API SBMemoryRegionInfoList +{ +public: + + SBMemoryRegionInfoList (); + + SBMemoryRegionInfoList (const lldb::SBMemoryRegionInfoList &rhs); + + const SBMemoryRegionInfoList & + operator = (const SBMemoryRegionInfoList &rhs); + + ~SBMemoryRegionInfoList (); + + uint32_t + GetSize () const; + + bool + GetMemoryRegionAtIndex (uint32_t idx, SBMemoryRegionInfo ®ion_info); + + void + Append (lldb::SBMemoryRegionInfo ®ion); + + void + Append (lldb::SBMemoryRegionInfoList ®ion_list); + + void + Clear (); + +protected: + + const MemoryRegionInfoListImpl * + operator->() const; + + const MemoryRegionInfoListImpl & + operator*() const; + +private: + + std::unique_ptr<MemoryRegionInfoListImpl> m_opaque_ap; + +}; + +} // namespace lldb + +#endif // LLDB_SBMemoryRegionInfoList_h_ diff --git a/include/lldb/API/SBProcess.h b/include/lldb/API/SBProcess.h index 1a9cc8022880..a8881ad898c0 100644 --- a/include/lldb/API/SBProcess.h +++ b/include/lldb/API/SBProcess.h @@ -393,6 +393,34 @@ public: lldb::SBError SaveCore(const char *file_name); + //------------------------------------------------------------------ + /// Query the address load_addr and store the details of the memory + /// region that contains it in the supplied SBMemoryRegionInfo object. + /// To iterate over all memory regions use GetMemoryRegionList. + /// + /// @param[in] load_addr + /// The address to be queried. + /// + /// @param[out] region_info + /// A reference to an SBMemoryRegionInfo object that will contain + /// the details of the memory region containing load_addr. + /// + /// @return + /// An error object describes any errors that occurred while + /// querying load_addr. + //------------------------------------------------------------------ + lldb::SBError + GetMemoryRegionInfo (lldb::addr_t load_addr, lldb::SBMemoryRegionInfo ®ion_info); + + //------------------------------------------------------------------ + /// Return the list of memory regions within the process. + /// + /// @return + /// A list of all witin the process memory regions. + //------------------------------------------------------------------ + lldb::SBMemoryRegionInfoList + GetMemoryRegions(); + protected: friend class SBAddress; friend class SBBreakpoint; diff --git a/include/lldb/API/SBStream.h b/include/lldb/API/SBStream.h index e62723c2f37e..717979977d16 100644 --- a/include/lldb/API/SBStream.h +++ b/include/lldb/API/SBStream.h @@ -76,6 +76,7 @@ protected: friend class SBInstruction; friend class SBInstructionList; friend class SBLineEntry; + friend class SBMemoryRegionInfo; friend class SBModule; friend class SBModuleSpec; friend class SBModuleSpecList; diff --git a/include/lldb/API/SBStringList.h b/include/lldb/API/SBStringList.h index e0e58f765c6d..bc8ff935eda3 100644 --- a/include/lldb/API/SBStringList.h +++ b/include/lldb/API/SBStringList.h @@ -45,6 +45,9 @@ public: const char * GetStringAtIndex (size_t idx); + const char * + GetStringAtIndex (size_t idx) const; + void Clear (); diff --git a/include/lldb/API/SBTarget.h b/include/lldb/API/SBTarget.h index 723c433b521a..0bcabd043c9c 100644 --- a/include/lldb/API/SBTarget.h +++ b/include/lldb/API/SBTarget.h @@ -621,6 +621,9 @@ public: BreakpointCreateByLocation (const lldb::SBFileSpec &file_spec, uint32_t line); lldb::SBBreakpoint + BreakpointCreateByLocation (const lldb::SBFileSpec &file_spec, uint32_t line, lldb::addr_t offset); + + lldb::SBBreakpoint BreakpointCreateByName(const char *symbol_name, const char *module_name = nullptr); // This version uses name_type_mask = eFunctionNameTypeAuto @@ -658,6 +661,15 @@ public: const SBFileSpecList &comp_unit_list); lldb::SBBreakpoint + BreakpointCreateByNames (const char *symbol_name[], + uint32_t num_names, + uint32_t name_type_mask, // Logical OR one or more FunctionNameType enum bits + lldb::LanguageType symbol_language, + lldb::addr_t offset, + const SBFileSpecList &module_list, + const SBFileSpecList &comp_unit_list); + + lldb::SBBreakpoint BreakpointCreateByRegex (const char *symbol_name_regex, const char *module_name = nullptr); lldb::SBBreakpoint @@ -682,6 +694,12 @@ public: const SBFileSpecList &source_file); lldb::SBBreakpoint + BreakpointCreateBySourceRegex (const char *source_regex, + const SBFileSpecList &module_list, + const SBFileSpecList &source_file, + const SBStringList &func_names); + + lldb::SBBreakpoint BreakpointCreateForException (lldb::LanguageType language, bool catch_bp, bool throw_bp); diff --git a/include/lldb/API/SBThread.h b/include/lldb/API/SBThread.h index 2c45fa8d5120..c1ce216f9be6 100644 --- a/include/lldb/API/SBThread.h +++ b/include/lldb/API/SBThread.h @@ -82,6 +82,9 @@ public: bool GetStopReasonExtendedInfoAsJSON (lldb::SBStream &stream); + SBThreadCollection + GetStopReasonExtendedBacktraces (InstrumentationRuntimeType type); + size_t GetStopDescription (char *dst, size_t dst_len); @@ -116,6 +119,12 @@ public: StepInto (const char *target_name, lldb::RunMode stop_other_threads = lldb::eOnlyDuringStepping); void + StepInto (const char *target_name, + uint32_t end_line, + SBError &error, + lldb::RunMode stop_other_threads = lldb::eOnlyDuringStepping); + + void StepOut (); void @@ -141,6 +150,9 @@ public: SBError ReturnFromFrame (SBFrame &frame, SBValue &return_value); + SBError + UnwindInnermostExpression(); + //-------------------------------------------------------------------------- /// LLDB currently supports process centric debugging which means when any /// thread in a process stops, all other threads are stopped. The Suspend() diff --git a/include/lldb/API/SBThreadCollection.h b/include/lldb/API/SBThreadCollection.h index 996ee3cd22aa..79f977454497 100644 --- a/include/lldb/API/SBThreadCollection.h +++ b/include/lldb/API/SBThreadCollection.h @@ -58,6 +58,7 @@ protected: private: friend class SBProcess; + friend class SBThread; lldb::ThreadCollectionSP m_opaque_sp; }; diff --git a/include/lldb/API/SBValue.h b/include/lldb/API/SBValue.h index a7e015064f96..b9f1e6f5c93f 100644 --- a/include/lldb/API/SBValue.h +++ b/include/lldb/API/SBValue.h @@ -125,6 +125,12 @@ public: bool IsSynthetic (); + + bool + IsSyntheticChildrenGenerated (); + + void + SetSyntheticChildrenGenerated (bool); const char * GetLocation (); diff --git a/include/lldb/Breakpoint/BreakpointList.h b/include/lldb/Breakpoint/BreakpointList.h index f4837e1ce956..5ddde7d837c4 100644 --- a/include/lldb/Breakpoint/BreakpointList.h +++ b/include/lldb/Breakpoint/BreakpointList.h @@ -13,10 +13,11 @@ // C Includes // C++ Includes #include <list> +#include <mutex> + // Other libraries and framework includes // Project includes #include "lldb/Breakpoint/Breakpoint.h" -#include "lldb/Host/Mutex.h" namespace lldb_private { @@ -116,7 +117,7 @@ public: size_t GetSize() const { - Mutex::Locker locker(m_mutex); + std::lock_guard<std::recursive_mutex> guard(m_mutex); return m_breakpoints.size(); } @@ -193,7 +194,7 @@ public: /// The locker object that is set. //------------------------------------------------------------------ void - GetListMutex (lldb_private::Mutex::Locker &locker); + GetListMutex(std::unique_lock<std::recursive_mutex> &lock); protected: typedef std::list<lldb::BreakpointSP> bp_collection; @@ -204,19 +205,20 @@ protected: bp_collection::const_iterator GetBreakpointIDConstIterator(lldb::break_id_t breakID) const; - Mutex & - GetMutex () const + std::recursive_mutex & + GetMutex() const { return m_mutex; } - mutable Mutex m_mutex; + mutable std::recursive_mutex m_mutex; bp_collection m_breakpoints; // The breakpoint list, currently a list. lldb::break_id_t m_next_break_id; bool m_is_internal; public: - typedef LockingAdaptedIterable<bp_collection, lldb::BreakpointSP, list_adapter> BreakpointIterable; + typedef LockingAdaptedIterable<bp_collection, lldb::BreakpointSP, list_adapter, std::recursive_mutex> + BreakpointIterable; BreakpointIterable Breakpoints() { diff --git a/include/lldb/Breakpoint/BreakpointLocation.h b/include/lldb/Breakpoint/BreakpointLocation.h index 58d144cfb668..42eca73dbb22 100644 --- a/include/lldb/Breakpoint/BreakpointLocation.h +++ b/include/lldb/Breakpoint/BreakpointLocation.h @@ -13,6 +13,7 @@ // C Includes // C++ Includes #include <memory> +#include <mutex> // Other libraries and framework includes // Project includes @@ -20,7 +21,6 @@ #include "lldb/Breakpoint/StoppointLocation.h" #include "lldb/Core/Address.h" #include "lldb/Core/UserID.h" -#include "lldb/Host/Mutex.h" namespace lldb_private { @@ -460,7 +460,8 @@ private: std::unique_ptr<BreakpointOptions> m_options_ap; ///< Breakpoint options pointer, nullptr if we're using our breakpoint's options. lldb::BreakpointSiteSP m_bp_site_sp; ///< Our breakpoint site (it may be shared by more than one location.) lldb::UserExpressionSP m_user_expression_sp; ///< The compiled expression to use in testing our condition. - Mutex m_condition_mutex; ///< Guards parsing and evaluation of the condition, which could be evaluated by multiple processes. + std::mutex m_condition_mutex; ///< Guards parsing and evaluation of the condition, which could be evaluated by + /// multiple processes. size_t m_condition_hash; ///< For testing whether the condition source code changed. void diff --git a/include/lldb/Breakpoint/BreakpointLocationCollection.h b/include/lldb/Breakpoint/BreakpointLocationCollection.h index 004f8395122b..1a016544fa4c 100644 --- a/include/lldb/Breakpoint/BreakpointLocationCollection.h +++ b/include/lldb/Breakpoint/BreakpointLocationCollection.h @@ -13,6 +13,8 @@ // C Includes // C++ Includes #include <vector> +#include <mutex> + // Other libraries and framework includes // Project includes #include "lldb/lldb-private.h" @@ -201,7 +203,8 @@ private: collection::const_iterator GetIDPairConstIterator(lldb::break_id_t break_id, lldb::break_id_t break_loc_id) const; - collection m_break_loc_collection; + collection m_break_loc_collection; + mutable std::mutex m_collection_mutex; public: typedef AdaptedIterable<collection, lldb::BreakpointLocationSP, vector_adapter> BreakpointLocationCollectionIterable; diff --git a/include/lldb/Breakpoint/BreakpointLocationList.h b/include/lldb/Breakpoint/BreakpointLocationList.h index 81526089b427..1fbfa43a40f4 100644 --- a/include/lldb/Breakpoint/BreakpointLocationList.h +++ b/include/lldb/Breakpoint/BreakpointLocationList.h @@ -13,13 +13,13 @@ // C Includes // C++ Includes #include <map> +#include <mutex> #include <vector> // Other libraries and framework includes // Project includes #include "lldb/lldb-private.h" #include "lldb/Core/Address.h" -#include "lldb/Host/Mutex.h" #include "lldb/Utility/Iterable.h" namespace lldb_private { @@ -270,7 +270,7 @@ protected: Breakpoint &m_owner; collection m_locations; // Vector of locations, sorted by ID addr_map m_address_to_location; - mutable Mutex m_mutex; + mutable std::recursive_mutex m_mutex; lldb::break_id_t m_next_id; BreakpointLocationCollection *m_new_location_recorder; diff --git a/include/lldb/Breakpoint/BreakpointResolver.h b/include/lldb/Breakpoint/BreakpointResolver.h index 198abed841b2..b117e668a1bd 100644 --- a/include/lldb/Breakpoint/BreakpointResolver.h +++ b/include/lldb/Breakpoint/BreakpointResolver.h @@ -60,7 +60,7 @@ public: /// @result /// Returns breakpoint location id. //------------------------------------------------------------------ - BreakpointResolver (Breakpoint *bkpt, unsigned char resolverType); + BreakpointResolver (Breakpoint *bkpt, unsigned char resolverType, lldb::addr_t offset = 0); //------------------------------------------------------------------ /// The Destructor is virtual, all significant breakpoint resolvers derive @@ -78,6 +78,29 @@ public: SetBreakpoint (Breakpoint *bkpt); //------------------------------------------------------------------ + /// This updates the offset for this breakpoint. All the locations currently + /// set for this breakpoint will have their offset adjusted when this is called. + /// + /// @param[in] offset + /// The offset to add to all locations. + //------------------------------------------------------------------ + void + SetOffset (lldb::addr_t offset); + + //------------------------------------------------------------------ + /// This updates the offset for this breakpoint. All the locations currently + /// set for this breakpoint will have their offset adjusted when this is called. + /// + /// @param[in] offset + /// The offset to add to all locations. + //------------------------------------------------------------------ + lldb::addr_t + GetOffset () const + { + return m_offset; + } + + //------------------------------------------------------------------ /// In response to this method the resolver scans all the modules in the breakpoint's /// target, and adds any new locations it finds. /// @@ -145,8 +168,12 @@ protected: /// matching addresses to unique entries, and skip the prologue if asked to do so, and then set /// breakpoint locations in this breakpoint for all the resultant addresses. void SetSCMatchesByLine (SearchFilter &filter, SymbolContextList &sc_list, bool skip_prologue, const char *log_ident); + + lldb::BreakpointLocationSP + AddLocation(Address loc_addr, bool *new_location = NULL); Breakpoint *m_breakpoint; // This is the breakpoint we add locations to. + lldb::addr_t m_offset; // A random offset the user asked us to add to any breakpoints we set. private: // Subclass identifier (for llvm isa/dyn_cast) diff --git a/include/lldb/Breakpoint/BreakpointResolverFileLine.h b/include/lldb/Breakpoint/BreakpointResolverFileLine.h index 2dde1546f126..cea192b5edbf 100644 --- a/include/lldb/Breakpoint/BreakpointResolverFileLine.h +++ b/include/lldb/Breakpoint/BreakpointResolverFileLine.h @@ -31,6 +31,7 @@ public: BreakpointResolverFileLine (Breakpoint *bkpt, const FileSpec &resolver, uint32_t line_no, + lldb::addr_t m_offset, bool check_inlines, bool skip_prologue, bool exact_match); diff --git a/include/lldb/Breakpoint/BreakpointResolverFileRegex.h b/include/lldb/Breakpoint/BreakpointResolverFileRegex.h index a8d7a50b5d93..ce67c2dc98ec 100644 --- a/include/lldb/Breakpoint/BreakpointResolverFileRegex.h +++ b/include/lldb/Breakpoint/BreakpointResolverFileRegex.h @@ -12,9 +12,11 @@ // C Includes // C++ Includes +#include <set> // Other libraries and framework includes // Project includes #include "lldb/Breakpoint/BreakpointResolver.h" +#include "lldb/Core/ConstString.h" namespace lldb_private { @@ -30,6 +32,7 @@ class BreakpointResolverFileRegex : public: BreakpointResolverFileRegex (Breakpoint *bkpt, RegularExpression ®ex, + const std::unordered_set<std::string> &func_name_set, bool exact_match); ~BreakpointResolverFileRegex() override; @@ -48,6 +51,9 @@ public: void Dump (Stream *s) const override; + + void + AddFunctionName(const char *func_name); /// Methods for support type inquiry through isa, cast, and dyn_cast: static inline bool classof(const BreakpointResolverFileRegex *) { return true; } @@ -61,7 +67,8 @@ public: protected: friend class Breakpoint; RegularExpression m_regex; // This is the line expression that we are looking for. - bool m_exact_match; + bool m_exact_match; // If true, then if the source we match is in a comment, we won't set a location there. + std::unordered_set<std::string> m_function_names; // Limit the search to functions in the comp_unit passed in. private: DISALLOW_COPY_AND_ASSIGN(BreakpointResolverFileRegex); diff --git a/include/lldb/Breakpoint/BreakpointResolverName.h b/include/lldb/Breakpoint/BreakpointResolverName.h index aaae9c1a12cf..a11359dd0094 100644 --- a/include/lldb/Breakpoint/BreakpointResolverName.h +++ b/include/lldb/Breakpoint/BreakpointResolverName.h @@ -18,6 +18,7 @@ // Other libraries and framework includes // Project includes #include "lldb/Breakpoint/BreakpointResolver.h" +#include "lldb/Core/Module.h" namespace lldb_private { @@ -37,6 +38,7 @@ public: uint32_t name_type_mask, lldb::LanguageType language, Breakpoint::MatchType type, + lldb::addr_t offset, bool skip_prologue); // This one takes an array of names. It is always MatchType = Exact. @@ -45,6 +47,7 @@ public: size_t num_names, uint32_t name_type_mask, lldb::LanguageType language, + lldb::addr_t offset, bool skip_prologue); // This one takes a C++ array of names. It is always MatchType = Exact. @@ -52,18 +55,21 @@ public: std::vector<std::string> names, uint32_t name_type_mask, lldb::LanguageType language, + lldb::addr_t offset, bool skip_prologue); // Creates a function breakpoint by regular expression. Takes over control of the lifespan of func_regex. BreakpointResolverName (Breakpoint *bkpt, RegularExpression &func_regex, lldb::LanguageType language, + lldb::addr_t offset, bool skip_prologue); BreakpointResolverName (Breakpoint *bkpt, const char *class_name, const char *method, Breakpoint::MatchType type, + lldb::addr_t offset, bool skip_prologue); ~BreakpointResolverName() override; @@ -95,26 +101,7 @@ public: protected: BreakpointResolverName(const BreakpointResolverName &rhs); - struct LookupInfo - { - ConstString name; - ConstString lookup_name; - uint32_t name_type_mask; // See FunctionNameType - bool match_name_after_lookup; - - LookupInfo () : - name(), - lookup_name(), - name_type_mask (0), - match_name_after_lookup (false) - { - } - - void - Prune (SymbolContextList &sc_list, - size_t start_idx) const; - }; - std::vector<LookupInfo> m_lookups; + std::vector<Module::LookupInfo> m_lookups; ConstString m_class_name; RegularExpression m_regex; Breakpoint::MatchType m_match_type; diff --git a/include/lldb/Breakpoint/BreakpointSite.h b/include/lldb/Breakpoint/BreakpointSite.h index 6cebcab8e2db..27a23527d9fa 100644 --- a/include/lldb/Breakpoint/BreakpointSite.h +++ b/include/lldb/Breakpoint/BreakpointSite.h @@ -14,12 +14,12 @@ // C++ Includes #include <list> +#include <mutex> // Other libraries and framework includes // Project includes #include "lldb/lldb-forward.h" -#include "lldb/Host/Mutex.h" #include "lldb/Core/UserID.h" #include "lldb/Breakpoint/StoppointLocation.h" #include "lldb/Breakpoint/BreakpointLocationCollection.h" @@ -297,7 +297,7 @@ private: // Consider adding an optimization where if there is only one // owner, we don't store a list. The usual case will be only one owner... BreakpointLocationCollection m_owners; ///< This has the BreakpointLocations that share this breakpoint site. - Mutex m_owners_mutex; ///< This mutex protects the owners collection. + std::recursive_mutex m_owners_mutex; ///< This mutex protects the owners collection. static lldb::break_id_t GetNextID(); diff --git a/include/lldb/Breakpoint/BreakpointSiteList.h b/include/lldb/Breakpoint/BreakpointSiteList.h index d7bb8fd777ef..e681aa3599f7 100644 --- a/include/lldb/Breakpoint/BreakpointSiteList.h +++ b/include/lldb/Breakpoint/BreakpointSiteList.h @@ -12,12 +12,13 @@ // C Includes // C++ Includes -#include <map> #include <functional> +#include <map> +#include <mutex> + // Other libraries and framework includes // Project includes #include "lldb/Breakpoint/BreakpointSite.h" -#include "lldb/Host/Mutex.h" namespace lldb_private { @@ -189,16 +190,17 @@ public: size_t GetSize() const { - Mutex::Locker locker(m_mutex); + std::lock_guard<std::recursive_mutex> guard(m_mutex); return m_bp_site_list.size(); } bool IsEmpty() const { - Mutex::Locker locker(m_mutex); + std::lock_guard<std::recursive_mutex> guard(m_mutex); return m_bp_site_list.empty(); } + protected: typedef std::map<lldb::addr_t, lldb::BreakpointSiteSP> collection; @@ -208,7 +210,7 @@ protected: collection::const_iterator GetIDConstIterator(lldb::break_id_t breakID) const; - mutable Mutex m_mutex; + mutable std::recursive_mutex m_mutex; collection m_bp_site_list; // The breakpoint site list. }; diff --git a/include/lldb/Breakpoint/WatchpointList.h b/include/lldb/Breakpoint/WatchpointList.h index d16cb25e3b7d..7369623d1ce2 100644 --- a/include/lldb/Breakpoint/WatchpointList.h +++ b/include/lldb/Breakpoint/WatchpointList.h @@ -13,12 +13,13 @@ // C Includes // C++ Includes #include <list> +#include <mutex> #include <vector> + // Other libraries and framework includes // Project includes #include "lldb/lldb-private.h" #include "lldb/Core/Address.h" -#include "lldb/Host/Mutex.h" namespace lldb_private { @@ -217,7 +218,7 @@ public: size_t GetSize() const { - Mutex::Locker locker(m_mutex); + std::lock_guard<std::recursive_mutex> guard(m_mutex); return m_watchpoints.size(); } @@ -250,7 +251,7 @@ public: /// The locker object that is set. //------------------------------------------------------------------ void - GetListMutex (lldb_private::Mutex::Locker &locker); + GetListMutex(std::unique_lock<std::recursive_mutex> &lock); protected: typedef std::list<lldb::WatchpointSP> wp_collection; @@ -266,7 +267,7 @@ protected: GetIDConstIterator(lldb::watch_id_t watchID) const; wp_collection m_watchpoints; - mutable Mutex m_mutex; + mutable std::recursive_mutex m_mutex; lldb::watch_id_t m_next_wp_id; }; diff --git a/include/lldb/Core/ArchSpec.h b/include/lldb/Core/ArchSpec.h index 13ff436cf08f..be760637c03e 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 8e59a41805ec..33172fa73780 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 d29aaca9c2ea..8913f1631a8b 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 6e234da0a595..c678168790a8 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 d5cb5e8ba4bc..51ecade2d374 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 4ca648ca296e..7a969457eef6 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 c5e60022fc96..36fff43bf6bc 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 e8867c0e7e77..1ae0fc83b27e 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 fbb7bd8b0c1a..164d1bfb651b 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 3eba1c3cc9d8..1844df365158 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 b11c1644507b..1057cf35c6db 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 ca04c84b21a6..da8c0d8f5bb6 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 5a52ab2b8b2d..b7cf3b02e01e 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 35b182aa9801..46fa330fb19c 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 a0dd43263a2c..38a91b0bf0ee 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 95de7f375736..245cb2365b2e 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 28d3083979d6..eb68859aed3f 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 030b849212c4..0626b5f2c857 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 a476cd3bd867..be2176e2b50e 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 3d5e1fb39b43..5c76fb5aad30 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 8c92f1ba667e..0837e326f97b 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 e5a9da7512bb..9e91eb94a74c 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 7ab619b3bb79..6059e0e1f8e9 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 4235edc92ade..4a885ff1a480 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 000000000000..dd90d49afcb8 --- /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 42a5a5c6725a..cad36a0c1637 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 ffaeba6fce9b..4d89700644cc 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 7e72b89ad8e6..6c395c81c37b 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 a6d934afd294..7539b550dc42 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 c066cc7d3661..bef158feb39d 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 f63ee83284df..892df8c62cc5 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 395820dad6c7..84dd79213d02 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 356d175a64ae..e4a238a96c8f 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 36b82f00a240..848a221c3d05 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 80f37f104765..8a045c3b0db1 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 05bc3781a3cc..38d9f7b5ade1 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; diff --git a/include/lldb/DataFormatters/DumpValueObjectOptions.h b/include/lldb/DataFormatters/DumpValueObjectOptions.h index f65ee7b95845..e90bd1bcadcd 100644 --- a/include/lldb/DataFormatters/DumpValueObjectOptions.h +++ b/include/lldb/DataFormatters/DumpValueObjectOptions.h @@ -152,6 +152,9 @@ public: DumpValueObjectOptions& SetRevealEmptyAggregates (bool reveal = true); + + DumpValueObjectOptions& + SetElementCount (uint32_t element_count = 0); public: uint32_t m_max_depth = UINT32_MAX; @@ -163,6 +166,7 @@ public: lldb::LanguageType m_varformat_language = lldb::eLanguageTypeUnknown; PointerDepth m_max_ptr_depth; DeclPrintingHelper m_decl_printing_helper; + uint32_t m_element_count = 0; bool m_use_synthetic : 1; bool m_scope_already_checked : 1; bool m_flat_output : 1; diff --git a/include/lldb/DataFormatters/FormatCache.h b/include/lldb/DataFormatters/FormatCache.h index 9f1e078f7199..645fbc7ddf10 100644 --- a/include/lldb/DataFormatters/FormatCache.h +++ b/include/lldb/DataFormatters/FormatCache.h @@ -13,12 +13,12 @@ // C Includes // C++ Includes #include <map> +#include <mutex> // Other libraries and framework includes // Project includes #include "lldb/lldb-public.h" #include "lldb/Core/ConstString.h" -#include "lldb/Host/Mutex.h" namespace lldb_private { class FormatCache @@ -82,8 +82,8 @@ private: }; typedef std::map<ConstString,Entry> CacheMap; CacheMap m_map; - Mutex m_mutex; - + std::recursive_mutex m_mutex; + uint64_t m_cache_hits; uint64_t m_cache_misses; diff --git a/include/lldb/DataFormatters/FormatManager.h b/include/lldb/DataFormatters/FormatManager.h index 24ba5a7f0aa5..27dc31d259d0 100644 --- a/include/lldb/DataFormatters/FormatManager.h +++ b/include/lldb/DataFormatters/FormatManager.h @@ -15,6 +15,7 @@ #include <atomic> #include <initializer_list> #include <map> +#include <mutex> #include <vector> // Other libraries and framework includes @@ -289,7 +290,7 @@ private: std::atomic<uint32_t> m_last_revision; FormatCache m_format_cache; - Mutex m_language_categories_mutex; + std::recursive_mutex m_language_categories_mutex; LanguageCategories m_language_categories_map; NamedSummariesMap m_named_summaries_map; TypeCategoryMap m_categories_map; diff --git a/include/lldb/DataFormatters/FormattersContainer.h b/include/lldb/DataFormatters/FormattersContainer.h index dcd08211f19b..c4694463b676 100644 --- a/include/lldb/DataFormatters/FormattersContainer.h +++ b/include/lldb/DataFormatters/FormattersContainer.h @@ -15,6 +15,7 @@ #include <functional> #include <map> #include <memory> +#include <mutex> #include <string> // Other libraries and framework includes @@ -81,33 +82,27 @@ public: typedef std::map<KeyType, ValueSP> MapType; typedef typename MapType::iterator MapIterator; typedef std::function<bool(KeyType, const ValueSP&)> ForEachCallback; - - FormatMap(IFormatChangeListener* lst) : - m_map(), - m_map_mutex(Mutex::eMutexTypeRecursive), - listener(lst) - { - } - + + FormatMap(IFormatChangeListener *lst) : m_map(), m_map_mutex(), listener(lst) {} + void - Add(KeyType name, - const ValueSP& entry) + Add(KeyType name, const ValueSP &entry) { if (listener) entry->GetRevision() = listener->GetCurrentRevision(); else entry->GetRevision() = 0; - Mutex::Locker locker(m_map_mutex); + std::lock_guard<std::recursive_mutex> guard(m_map_mutex); m_map[name] = entry; if (listener) listener->Changed(); } - + bool - Delete (KeyType name) + Delete(KeyType name) { - Mutex::Locker locker(m_map_mutex); + std::lock_guard<std::recursive_mutex> guard(m_map_mutex); MapIterator iter = m_map.find(name); if (iter == m_map.end()) return false; @@ -116,34 +111,33 @@ public: listener->Changed(); return true; } - + void - Clear () + Clear() { - Mutex::Locker locker(m_map_mutex); + std::lock_guard<std::recursive_mutex> guard(m_map_mutex); m_map.clear(); if (listener) listener->Changed(); } - + bool - Get(KeyType name, - ValueSP& entry) + Get(KeyType name, ValueSP &entry) { - Mutex::Locker locker(m_map_mutex); + std::lock_guard<std::recursive_mutex> guard(m_map_mutex); MapIterator iter = m_map.find(name); if (iter == m_map.end()) return false; entry = iter->second; return true; } - + void - ForEach (ForEachCallback callback) + ForEach(ForEachCallback callback) { if (callback) { - Mutex::Locker locker(m_map_mutex); + std::lock_guard<std::recursive_mutex> guard(m_map_mutex); MapIterator pos, end = m_map.end(); for (pos = m_map.begin(); pos != end; pos++) { @@ -153,17 +147,17 @@ public: } } } - + uint32_t GetCount () { return m_map.size(); } - + ValueSP - GetValueAtIndex (size_t index) + GetValueAtIndex(size_t index) { - Mutex::Locker locker(m_map_mutex); + std::lock_guard<std::recursive_mutex> guard(m_map_mutex); MapIterator iter = m_map.begin(); MapIterator end = m_map.end(); while (index > 0) @@ -175,11 +169,11 @@ public: } return iter->second; } - + KeyType - GetKeyAtIndex (size_t index) + GetKeyAtIndex(size_t index) { - Mutex::Locker locker(m_map_mutex); + std::lock_guard<std::recursive_mutex> guard(m_map_mutex); MapIterator iter = m_map.begin(); MapIterator end = m_map.end(); while (index > 0) @@ -191,24 +185,24 @@ public: } return iter->first; } - + protected: - MapType m_map; - Mutex m_map_mutex; + MapType m_map; + std::recursive_mutex m_map_mutex; IFormatChangeListener* listener; - + MapType& map () { return m_map; } - - Mutex& - mutex () + + std::recursive_mutex & + mutex() { return m_map_mutex; } - + friend class FormattersContainer<KeyType, ValueType>; friend class FormatManager; }; @@ -332,24 +326,23 @@ protected: } bool - Delete_Impl (ConstString type, lldb::RegularExpressionSP *dummy) - { - Mutex& x_mutex = m_format_map.mutex(); - lldb_private::Mutex::Locker locker(x_mutex); - MapIterator pos, end = m_format_map.map().end(); - for (pos = m_format_map.map().begin(); pos != end; pos++) - { - lldb::RegularExpressionSP regex = pos->first; - if ( ::strcmp(type.AsCString(),regex->GetText()) == 0) - { - m_format_map.map().erase(pos); - if (m_format_map.listener) - m_format_map.listener->Changed(); - return true; - } - } - return false; - } + Delete_Impl(ConstString type, lldb::RegularExpressionSP *dummy) + { + std::lock_guard<std::recursive_mutex> guard(m_format_map.mutex()); + MapIterator pos, end = m_format_map.map().end(); + for (pos = m_format_map.map().begin(); pos != end; pos++) + { + lldb::RegularExpressionSP regex = pos->first; + if (::strcmp(type.AsCString(), regex->GetText()) == 0) + { + m_format_map.map().erase(pos); + if (m_format_map.listener) + m_format_map.listener->Changed(); + return true; + } + } + return false; + } bool Get_Impl (ConstString type, MapValueType& entry, ConstString *dummy) @@ -385,36 +378,34 @@ protected: } bool - Get_Impl (ConstString key, MapValueType& value, lldb::RegularExpressionSP *dummy) - { - const char* key_cstr = key.AsCString(); - if (!key_cstr) - return false; - Mutex& x_mutex = m_format_map.mutex(); - lldb_private::Mutex::Locker locker(x_mutex); - MapIterator pos, end = m_format_map.map().end(); - for (pos = m_format_map.map().begin(); pos != end; pos++) - { - lldb::RegularExpressionSP regex = pos->first; - if (regex->Execute(key_cstr)) - { - value = pos->second; - return true; - } - } - return false; + Get_Impl(ConstString key, MapValueType &value, lldb::RegularExpressionSP *dummy) + { + const char *key_cstr = key.AsCString(); + if (!key_cstr) + return false; + std::lock_guard<std::recursive_mutex> guard(m_format_map.mutex()); + MapIterator pos, end = m_format_map.map().end(); + for (pos = m_format_map.map().begin(); pos != end; pos++) + { + lldb::RegularExpressionSP regex = pos->first; + if (regex->Execute(key_cstr)) + { + value = pos->second; + return true; + } + } + return false; } - + bool - GetExact_Impl (ConstString key, MapValueType& value, lldb::RegularExpressionSP *dummy) + GetExact_Impl(ConstString key, MapValueType &value, lldb::RegularExpressionSP *dummy) { - Mutex& x_mutex = m_format_map.mutex(); - lldb_private::Mutex::Locker locker(x_mutex); + std::lock_guard<std::recursive_mutex> guard(m_format_map.mutex()); MapIterator pos, end = m_format_map.map().end(); for (pos = m_format_map.map().begin(); pos != end; pos++) { lldb::RegularExpressionSP regex = pos->first; - if (strcmp(regex->GetText(),key.AsCString()) == 0) + if (strcmp(regex->GetText(), key.AsCString()) == 0) { value = pos->second; return true; diff --git a/include/lldb/DataFormatters/FormattersHelpers.h b/include/lldb/DataFormatters/FormattersHelpers.h index 4627a61e94f1..0622230f6797 100644 --- a/include/lldb/DataFormatters/FormattersHelpers.h +++ b/include/lldb/DataFormatters/FormattersHelpers.h @@ -75,35 +75,7 @@ namespace lldb_private { ScriptedSyntheticChildren::Flags flags, bool regex = false); #endif - - StackFrame* - GetViableFrame (ExecutionContext exe_ctx); - - bool - ExtractValueFromObjCExpression (ValueObject &valobj, - const char* target_type, - const char* selector, - uint64_t &value); - - bool - ExtractSummaryFromObjCExpression (ValueObject &valobj, - const char* target_type, - const char* selector, - Stream &stream, - lldb::LanguageType lang_type); - - lldb::ValueObjectSP - CallSelectorOnObject (ValueObject &valobj, - const char* return_type, - const char* selector, - uint64_t index); - - lldb::ValueObjectSP - CallSelectorOnObject (ValueObject &valobj, - const char* return_type, - const char* selector, - const char* key); - + size_t ExtractIndexFromString (const char* item_name); diff --git a/include/lldb/DataFormatters/TypeCategory.h b/include/lldb/DataFormatters/TypeCategory.h index 075d31d1cf6f..c6d7d7b0f878 100644 --- a/include/lldb/DataFormatters/TypeCategory.h +++ b/include/lldb/DataFormatters/TypeCategory.h @@ -14,6 +14,7 @@ // C++ Includes #include <initializer_list> #include <memory> +#include <mutex> #include <string> #include <vector> @@ -519,9 +520,9 @@ namespace lldb_private { bool m_enabled; IFormatChangeListener* m_change_listener; - - Mutex m_mutex; - + + std::recursive_mutex m_mutex; + ConstString m_name; std::vector<lldb::LanguageType> m_languages; diff --git a/include/lldb/DataFormatters/TypeCategoryMap.h b/include/lldb/DataFormatters/TypeCategoryMap.h index 8afeaf87cec5..2cc589809a7c 100644 --- a/include/lldb/DataFormatters/TypeCategoryMap.h +++ b/include/lldb/DataFormatters/TypeCategoryMap.h @@ -15,6 +15,7 @@ #include <functional> #include <list> #include <map> +#include <mutex> // Other libraries and framework includes // Project includes @@ -131,8 +132,8 @@ namespace lldb_private { return ptr.get() == other.get(); } }; - - Mutex m_map_mutex; + + std::recursive_mutex m_map_mutex; IFormatChangeListener* listener; MapType m_map; @@ -147,12 +148,13 @@ namespace lldb_private { { return m_active_categories; } - - Mutex& mutex () + + std::recursive_mutex & + mutex() { return m_map_mutex; } - + friend class FormattersContainer<KeyType, ValueType>; friend class FormatManager; }; diff --git a/include/lldb/DataFormatters/TypeSynthetic.h b/include/lldb/DataFormatters/TypeSynthetic.h index 90e5730288c4..ceb600aed69a 100644 --- a/include/lldb/DataFormatters/TypeSynthetic.h +++ b/include/lldb/DataFormatters/TypeSynthetic.h @@ -91,6 +91,11 @@ namespace lldb_private { virtual lldb::ValueObjectSP GetSyntheticValue () { return nullptr; } + // if this function returns a non-empty ConstString, then clients are expected to use the return + // as the name of the type of this ValueObject for display purposes + virtual ConstString + GetSyntheticTypeName () { return ConstString(); } + typedef std::shared_ptr<SyntheticChildrenFrontEnd> SharedPointer; typedef std::unique_ptr<SyntheticChildrenFrontEnd> AutoPointer; @@ -607,6 +612,9 @@ namespace lldb_private { lldb::ValueObjectSP GetSyntheticValue() override; + ConstString + GetSyntheticTypeName () override; + typedef std::shared_ptr<SyntheticChildrenFrontEnd> SharedPointer; private: diff --git a/include/lldb/DataFormatters/ValueObjectPrinter.h b/include/lldb/DataFormatters/ValueObjectPrinter.h index 23d7ee2edf50..c7591b019685 100644 --- a/include/lldb/DataFormatters/ValueObjectPrinter.h +++ b/include/lldb/DataFormatters/ValueObjectPrinter.h @@ -153,6 +153,10 @@ protected: void PrintChildrenPostamble (bool print_dotdotdot); + lldb::ValueObjectSP + GenerateChild (ValueObject* synth_valobj, + size_t idx); + void PrintChild (lldb::ValueObjectSP child_sp, const DumpValueObjectOptions::PointerDepth& curr_ptr_depth); diff --git a/include/lldb/DataFormatters/VectorIterator.h b/include/lldb/DataFormatters/VectorIterator.h index 3d96ee4c093b..0bacd51ca63e 100644 --- a/include/lldb/DataFormatters/VectorIterator.h +++ b/include/lldb/DataFormatters/VectorIterator.h @@ -38,9 +38,7 @@ namespace lldb_private { size_t GetIndexOfChildWithName(const ConstString &name) override; - - ~VectorIteratorSyntheticFrontEnd() override; - + private: ExecutionContextRef m_exe_ctx_ref; ConstString m_item_name; diff --git a/include/lldb/Expression/DWARFExpression.h b/include/lldb/Expression/DWARFExpression.h index 3527c3b4b153..d984a419c5c9 100644 --- a/include/lldb/Expression/DWARFExpression.h +++ b/include/lldb/Expression/DWARFExpression.h @@ -10,11 +10,12 @@ #ifndef liblldb_DWARFExpression_h_ #define liblldb_DWARFExpression_h_ -#include "lldb/lldb-private.h" #include "lldb/Core/Address.h" #include "lldb/Core/DataExtractor.h" #include "lldb/Core/Error.h" #include "lldb/Core/Scalar.h" +#include "lldb/lldb-private.h" +#include <functional> class DWARFCompileUnit; @@ -166,7 +167,14 @@ public: bool Update_DW_OP_addr (lldb::addr_t file_addr); - + + bool + ContainsThreadLocalStorage() const; + + bool + LinkThreadLocalStorage(lldb::ModuleSP new_module_sp, + std::function<lldb::addr_t(lldb::addr_t file_addr)> const &link_address_callback); + //------------------------------------------------------------------ /// Make the expression parser read its location information from a /// given data source. Does not change the offset and length @@ -282,6 +290,7 @@ public: ClangExpressionDeclMap *decl_map, lldb::addr_t loclist_base_load_addr, const Value* initial_value_ptr, + const Value* object_address_ptr, Value& result, Error *error_ptr) const; @@ -296,6 +305,7 @@ public: RegisterContext *reg_ctx, lldb::addr_t loclist_base_load_addr, const Value* initial_value_ptr, + const Value* object_address_ptr, Value& result, Error *error_ptr) const; @@ -370,6 +380,7 @@ public: const lldb::offset_t length, const lldb::RegisterKind reg_set, const Value* initial_value_ptr, + const Value* object_address_ptr, Value& result, Error *error_ptr); diff --git a/include/lldb/Expression/DiagnosticManager.h b/include/lldb/Expression/DiagnosticManager.h new file mode 100644 index 000000000000..c294bdecf2b2 --- /dev/null +++ b/include/lldb/Expression/DiagnosticManager.h @@ -0,0 +1,212 @@ +//===-- DiagnosticManager.h -------------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef lldb_DiagnosticManager_h +#define lldb_DiagnosticManager_h + +#include "lldb/lldb-defines.h" +#include "lldb/lldb-types.h" + +#include <string> +#include <vector> + +namespace lldb_private +{ + +enum DiagnosticOrigin +{ + eDiagnosticOriginUnknown = 0, + eDiagnosticOriginLLDB, + eDiagnosticOriginClang, + eDiagnosticOriginGo, + eDiagnosticOriginSwift, + eDiagnosticOriginLLVM +}; + +enum DiagnosticSeverity +{ + eDiagnosticSeverityError, + eDiagnosticSeverityWarning, + eDiagnosticSeverityRemark +}; + +const uint32_t LLDB_INVALID_COMPILER_ID = UINT32_MAX; + +class Diagnostic +{ +friend class DiagnosticManager; + +public: + DiagnosticOrigin getKind() const { return m_origin; } + + static bool classof(const Diagnostic *diag) + { + DiagnosticOrigin kind = diag->getKind(); + switch (kind) + { + case eDiagnosticOriginUnknown: + case eDiagnosticOriginLLDB: + case eDiagnosticOriginGo: + case eDiagnosticOriginLLVM: + return true; + case eDiagnosticOriginClang: + case eDiagnosticOriginSwift: + return false; + } + } + + Diagnostic(const char *message, DiagnosticSeverity severity, DiagnosticOrigin origin, uint32_t compiler_id) : + m_message(message), + m_severity(severity), + m_origin(origin), + m_compiler_id(compiler_id) + { + } + + Diagnostic(const Diagnostic &rhs) : + m_message(rhs.m_message), + m_severity(rhs.m_severity), + m_origin(rhs.m_origin), + m_compiler_id(rhs.m_compiler_id) + { + } + + virtual ~Diagnostic() = default; + + virtual bool HasFixIts () const { return false; } + + DiagnosticSeverity + GetSeverity() const + { + return m_severity; + } + + uint32_t + GetCompilerID() const + { + return m_compiler_id; + } + + const char * + GetMessage() const + { + return m_message.c_str(); + } + + void AppendMessage(const char *message, bool precede_with_newline = true) + { + if (precede_with_newline) + m_message.push_back('\n'); + m_message.append(message); + } + +protected: + std::string m_message; + DiagnosticSeverity m_severity; + DiagnosticOrigin m_origin; + uint32_t m_compiler_id; // Compiler-specific diagnostic ID +}; + +typedef std::vector<Diagnostic *> DiagnosticList; + +class DiagnosticManager +{ +public: + void + Clear() + { + m_diagnostics.clear(); + m_fixed_expression.clear(); + } + + // The diagnostic manager holds a list of diagnostics, which are owned by the manager. + const DiagnosticList & + Diagnostics() + { + return m_diagnostics; + } + + ~DiagnosticManager() + { + for (Diagnostic *diag : m_diagnostics) + { + delete diag; + } + } + + bool + HasFixIts() + { + for (Diagnostic *diag : m_diagnostics) + { + if (diag->HasFixIts()) + return true; + } + return false; + } + + void + AddDiagnostic(const char *message, DiagnosticSeverity severity, DiagnosticOrigin origin, + uint32_t compiler_id = LLDB_INVALID_COMPILER_ID) + { + m_diagnostics.push_back(new Diagnostic(message, severity, origin, compiler_id)); + } + + void + AddDiagnostic(Diagnostic *diagnostic) + { + m_diagnostics.push_back(diagnostic); + } + + size_t + Printf(DiagnosticSeverity severity, const char *format, ...) __attribute__((format(printf, 3, 4))); + size_t + PutCString(DiagnosticSeverity severity, const char *cstr); + + void + AppendMessageToDiagnostic(const char *cstr) + { + if (m_diagnostics.size()) + { + m_diagnostics.back()->AppendMessage(cstr); + } + } + + // Returns a string containing errors in this format: + // + // "error: error text\n + // warning: warning text\n + // remark text\n" + std::string + GetString(char separator = '\n'); + + void + Dump(Log *log); + + const std::string & + GetFixedExpression() + { + return m_fixed_expression; + } + + // Moves fixed_expression to the internal storage. + void + SetFixedExpression(std::string fixed_expression) + { + m_fixed_expression = std::move(fixed_expression); + fixed_expression.clear(); + } + +protected: + DiagnosticList m_diagnostics; + std::string m_fixed_expression; +}; +} + +#endif /* lldb_DiagnosticManager_h */ diff --git a/include/lldb/Expression/ExpressionParser.h b/include/lldb/Expression/ExpressionParser.h index 49333e79bf5e..323e515e3bba 100644 --- a/include/lldb/Expression/ExpressionParser.h +++ b/include/lldb/Expression/ExpressionParser.h @@ -57,17 +57,34 @@ public: /// Parse a single expression and convert it to IR using Clang. Don't /// wrap the expression in anything at all. /// - /// @param[in] stream - /// The stream to print errors to. + /// @param[in] diagnostic_manager + /// The diagnostic manager in which to store the errors and warnings. /// /// @return /// The number of errors encountered during parsing. 0 means /// success. //------------------------------------------------------------------ virtual unsigned - Parse (Stream &stream) = 0; + Parse(DiagnosticManager &diagnostic_manager) = 0; //------------------------------------------------------------------ + /// Try to use the FixIts in the diagnostic_manager to rewrite the + /// expression. If successful, the rewritten expression is stored + /// in the diagnostic_manager, get it out with GetFixedExpression. + /// + /// @param[in] diagnostic_manager + /// The diagnostic manager containing fixit's to apply. + /// + /// @return + /// \b true if the rewrite was successful, \b false otherwise. + //------------------------------------------------------------------ + virtual bool + RewriteExpression(DiagnosticManager &diagnostic_manager) + { + return false; + } + + //------------------------------------------------------------------ /// Ready an already-parsed expression for execution, possibly /// evaluating it statically. /// diff --git a/include/lldb/Expression/ExpressionSourceCode.h b/include/lldb/Expression/ExpressionSourceCode.h index 2dd09378fcd2..33ceade45558 100644 --- a/include/lldb/Expression/ExpressionSourceCode.h +++ b/include/lldb/Expression/ExpressionSourceCode.h @@ -54,10 +54,17 @@ public: bool GetText (std::string &text, lldb::LanguageType wrapping_language, - bool const_object, bool static_method, ExecutionContext &exe_ctx) const; + // Given a string returned by GetText, find the beginning and end of the body passed to CreateWrapped. + // Return true if the bounds could be found. This will also work on text with FixItHints applied. + static bool + GetOriginalBodyBounds(std::string transformed_text, + lldb::LanguageType wrapping_language, + size_t &start_loc, + size_t &end_loc); + private: ExpressionSourceCode (const char *name, const char *prefix, diff --git a/include/lldb/Expression/ExpressionVariable.h b/include/lldb/Expression/ExpressionVariable.h index d8030ba1c257..451acb685bb7 100644 --- a/include/lldb/Expression/ExpressionVariable.h +++ b/include/lldb/Expression/ExpressionVariable.h @@ -16,6 +16,8 @@ #include <vector> // Other libraries and framework includes +#include "llvm/ADT/DenseMap.h" + // Project includes #include "lldb/lldb-public.h" #include "lldb/Core/ConstString.h" @@ -309,10 +311,19 @@ public: RemovePersistentVariable (lldb::ExpressionVariableSP variable) = 0; virtual lldb::addr_t - LookupSymbol (const ConstString &name) = 0; + LookupSymbol (const ConstString &name); + + void + RegisterExecutionUnit (lldb::IRExecutionUnitSP &execution_unit_sp); private: LLVMCastKind m_kind; + + typedef std::set<lldb::IRExecutionUnitSP> ExecutionUnitSet; + ExecutionUnitSet m_execution_units; ///< The execution units that contain valuable symbols. + + typedef llvm::DenseMap<const char *, lldb::addr_t> SymbolMap; + SymbolMap m_symbol_map; ///< The addresses of the symbols in m_execution_units. }; } // namespace lldb_private diff --git a/include/lldb/Expression/FunctionCaller.h b/include/lldb/Expression/FunctionCaller.h index c9a45811670f..3848073c654f 100644 --- a/include/lldb/Expression/FunctionCaller.h +++ b/include/lldb/Expression/FunctionCaller.h @@ -99,17 +99,23 @@ public: //------------------------------------------------------------------ /// Compile the wrapper function /// - /// @param[in] errors - /// The stream to print parser errors to. + /// @param[in] thread_to_use_sp + /// Compilation might end up calling functions. Pass in the thread you + /// want the compilation to use. If you pass in an empty ThreadSP it will + /// use the currently selected thread. + /// + /// @param[in] diagnostic_manager + /// The diagnostic manager to report parser errors to. /// /// @return /// The number of errors. //------------------------------------------------------------------ virtual unsigned - CompileFunction (Stream &errors) = 0; - + CompileFunction (lldb::ThreadSP thread_to_use_sp, + DiagnosticManager &diagnostic_manager) = 0; + //------------------------------------------------------------------ - /// Insert the default function wrapper and its default argument struct + /// Insert the default function wrapper and its default argument struct /// /// @param[in] exe_ctx /// The execution context to insert the function and its arguments @@ -120,16 +126,14 @@ public: /// be LLDB_INVALID_ADDRESS; if it is, a new structure is allocated /// and args_addr_ref is pointed to it. /// - /// @param[in] errors - /// The stream to write errors to. + /// @param[in] diagnostic_manager + /// The diagnostic manager to report errors to. /// /// @return /// True on success; false otherwise. //------------------------------------------------------------------ bool - InsertFunction (ExecutionContext &exe_ctx, - lldb::addr_t &args_addr_ref, - Stream &errors); + InsertFunction(ExecutionContext &exe_ctx, lldb::addr_t &args_addr_ref, DiagnosticManager &diagnostic_manager); //------------------------------------------------------------------ /// Insert the default function wrapper (using the JIT) @@ -138,17 +142,17 @@ public: /// The execution context to insert the function and its arguments /// into. /// - /// @param[in] errors - /// The stream to write errors to. + /// @param[in] diagnostic_manager + /// The diagnostic manager to report errors to. /// /// @return /// True on success; false otherwise. //------------------------------------------------------------------ - bool WriteFunctionWrapper (ExecutionContext &exe_ctx, - Stream &errors); - + bool + WriteFunctionWrapper(ExecutionContext &exe_ctx, DiagnosticManager &diagnostic_manager); + //------------------------------------------------------------------ - /// Insert the default function argument struct + /// Insert the default function argument struct /// /// @param[in] exe_ctx /// The execution context to insert the function and its arguments @@ -159,16 +163,16 @@ public: /// be LLDB_INVALID_ADDRESS; if it is, a new structure is allocated /// and args_addr_ref is pointed to it. /// - /// @param[in] errors - /// The stream to write errors to. + /// @param[in] diagnostic_manager + /// The diagnostic manager to report errors to. /// /// @return /// True on success; false otherwise. //------------------------------------------------------------------ - bool WriteFunctionArguments (ExecutionContext &exe_ctx, - lldb::addr_t &args_addr_ref, - Stream &errors); - + bool + WriteFunctionArguments(ExecutionContext &exe_ctx, lldb::addr_t &args_addr_ref, + DiagnosticManager &diagnostic_manager); + //------------------------------------------------------------------ /// Insert an argument struct with a non-default function address and /// non-default argument values @@ -185,16 +189,15 @@ public: /// @param[in] arg_values /// The values of the function's arguments. /// - /// @param[in] errors - /// The stream to write errors to. + /// @param[in] diagnostic_manager + /// The diagnostic manager to report errors to. /// /// @return /// True on success; false otherwise. //------------------------------------------------------------------ - bool WriteFunctionArguments (ExecutionContext &exe_ctx, - lldb::addr_t &args_addr_ref, - ValueList &arg_values, - Stream &errors); + bool + WriteFunctionArguments(ExecutionContext &exe_ctx, lldb::addr_t &args_addr_ref, ValueList &arg_values, + DiagnosticManager &diagnostic_manager); //------------------------------------------------------------------ /// Run the function this FunctionCaller was created with. @@ -211,8 +214,8 @@ public: /// for deallocating it. And if passed in with a value other than LLDB_INVALID_ADDRESS, /// this should point to an already allocated structure with the values already written. /// - /// @param[in] errors - /// Errors will be written here if there are any. + /// @param[in] diagnostic_manager + /// The diagnostic manager to report errors to. /// /// @param[in] options /// The options for this expression execution. @@ -224,12 +227,9 @@ public: /// Returns one of the ExpressionResults enum indicating function call status. //------------------------------------------------------------------ lldb::ExpressionResults - ExecuteFunction(ExecutionContext &exe_ctx, - lldb::addr_t *args_addr_ptr, - const EvaluateExpressionOptions &options, - Stream &errors, - Value &results); - + ExecuteFunction(ExecutionContext &exe_ctx, lldb::addr_t *args_addr_ptr, const EvaluateExpressionOptions &options, + DiagnosticManager &diagnostic_manager, Value &results); + //------------------------------------------------------------------ /// Get a thread plan to run the function this FunctionCaller was created with. /// @@ -243,8 +243,8 @@ public: /// @param[in] args_addr /// The address of the argument struct. /// - /// @param[in] errors - /// The stream to write errors to. + /// @param[in] diagnostic_manager + /// The diagnostic manager to report errors to. /// /// @param[in] stop_others /// True if other threads should pause during execution. @@ -256,11 +256,9 @@ public: /// A ThreadPlan shared pointer for executing the function. //------------------------------------------------------------------ lldb::ThreadPlanSP - GetThreadPlanToCallFunction (ExecutionContext &exe_ctx, - lldb::addr_t args_addr, - const EvaluateExpressionOptions &options, - Stream &errors); - + GetThreadPlanToCallFunction(ExecutionContext &exe_ctx, lldb::addr_t args_addr, + const EvaluateExpressionOptions &options, DiagnosticManager &diagnostic_manager); + //------------------------------------------------------------------ /// Get the result of the function from its struct /// diff --git a/include/lldb/Expression/IRDynamicChecks.h b/include/lldb/Expression/IRDynamicChecks.h index ef77d55f4b34..9f31a6eb01d6 100644 --- a/include/lldb/Expression/IRDynamicChecks.h +++ b/include/lldb/Expression/IRDynamicChecks.h @@ -61,8 +61,8 @@ public: /// Install the utility functions into a process. This binds the /// instance of DynamicCheckerFunctions to that process. /// - /// @param[in] error_stream - /// A stream to print errors on. + /// @param[in] diagnostic_manager + /// A diagnostic manager to report errors to. /// /// @param[in] exe_ctx /// The execution context to install the functions into. @@ -71,11 +71,12 @@ public: /// True on success; false on failure, or if the functions have /// already been installed. //------------------------------------------------------------------ - bool Install (Stream &error_stream, - ExecutionContext &exe_ctx); - - bool DoCheckersExplainStop (lldb::addr_t addr, Stream &message); - + bool + Install(DiagnosticManager &diagnostic_manager, ExecutionContext &exe_ctx); + + bool + DoCheckersExplainStop(lldb::addr_t addr, Stream &message); + std::unique_ptr<UtilityFunction> m_valid_pointer_check; std::unique_ptr<UtilityFunction> m_objc_object_check; }; diff --git a/include/lldb/Expression/IRExecutionUnit.h b/include/lldb/Expression/IRExecutionUnit.h index 86744b7b9726..d557a35d0b06 100644 --- a/include/lldb/Expression/IRExecutionUnit.h +++ b/include/lldb/Expression/IRExecutionUnit.h @@ -26,8 +26,8 @@ #include "lldb/lldb-private.h" #include "lldb/Core/DataBufferHeap.h" #include "lldb/Expression/IRMemoryMap.h" -#include "lldb/Host/Mutex.h" #include "lldb/Symbol/ObjectFile.h" +#include "lldb/Symbol/SymbolContext.h" namespace llvm { @@ -71,13 +71,19 @@ public: std::unique_ptr<llvm::Module> &module_ap, ConstString &name, const lldb::TargetSP &target_sp, + const SymbolContext &sym_ctx, std::vector<std::string> &cpu_features); //------------------------------------------------------------------ /// Destructor //------------------------------------------------------------------ ~IRExecutionUnit() override; - + + ConstString GetFunctionName() + { + return m_name; + } + llvm::Module * GetModule() { @@ -131,7 +137,83 @@ public: lldb::ModuleSP GetJITModule (); + + lldb::addr_t + FindSymbol(const ConstString &name); + void + GetStaticInitializers(std::vector <lldb::addr_t> &static_initializers); + + //---------------------------------------------------------------------- + /// @class JittedFunction IRExecutionUnit.h "lldb/Expression/IRExecutionUnit.h" + /// @brief Encapsulates a single function that has been generated by the JIT. + /// + /// Functions that have been generated by the JIT are first resident in the + /// local process, and then placed in the target process. JittedFunction + /// represents a function possibly resident in both. + //---------------------------------------------------------------------- + struct JittedEntity { + ConstString m_name; ///< The function's name + lldb::addr_t m_local_addr; ///< The address of the function in LLDB's memory + lldb::addr_t m_remote_addr; ///< The address of the function in the target's memory + + //------------------------------------------------------------------ + /// Constructor + /// + /// Initializes class variabes. + /// + /// @param[in] name + /// The name of the function. + /// + /// @param[in] local_addr + /// The address of the function in LLDB, or LLDB_INVALID_ADDRESS if + /// it is not present in LLDB's memory. + /// + /// @param[in] remote_addr + /// The address of the function in the target, or LLDB_INVALID_ADDRESS + /// if it is not present in the target's memory. + //------------------------------------------------------------------ + JittedEntity (const char *name, + lldb::addr_t local_addr = LLDB_INVALID_ADDRESS, + lldb::addr_t remote_addr = LLDB_INVALID_ADDRESS) : + m_name (name), + m_local_addr (local_addr), + m_remote_addr (remote_addr) + { + } + }; + + struct JittedFunction : JittedEntity + { + bool m_external; + JittedFunction (const char *name, + bool external, + lldb::addr_t local_addr = LLDB_INVALID_ADDRESS, + lldb::addr_t remote_addr = LLDB_INVALID_ADDRESS) : + JittedEntity (name, local_addr, remote_addr), + m_external(external) + {} + }; + + struct JittedGlobalVariable : JittedEntity + { + JittedGlobalVariable (const char *name, + lldb::addr_t local_addr = LLDB_INVALID_ADDRESS, + lldb::addr_t remote_addr = LLDB_INVALID_ADDRESS) : + JittedEntity (name, local_addr, remote_addr) + {} + }; + + const std::vector<JittedFunction> &GetJittedFunctions() + { + return m_jitted_functions; + } + + const std::vector<JittedGlobalVariable> &GetJittedGlobalVariables() + { + return m_jitted_global_variables; + } + private: //------------------------------------------------------------------ /// Look up the object in m_address_map that contains a given address, @@ -201,6 +283,33 @@ private: DisassembleFunction (Stream &stream, lldb::ProcessSP &process_sp); + struct SearchSpec; + + void + CollectCandidateCNames(std::vector<SearchSpec> &C_specs, + const ConstString &name); + + void + CollectCandidateCPlusPlusNames(std::vector<SearchSpec> &CPP_specs, + const std::vector<SearchSpec> &C_specs, + const SymbolContext &sc); + + void + CollectFallbackNames(std::vector<SearchSpec> &fallback_specs, + const std::vector<SearchSpec> &C_specs); + + lldb::addr_t + FindInSymbols(const std::vector<SearchSpec> &specs, + const lldb_private::SymbolContext &sc); + + lldb::addr_t + FindInRuntimes(const std::vector<SearchSpec> &specs, + const lldb_private::SymbolContext &sc); + + lldb::addr_t + FindInUserDefinedSymbols(const std::vector<SearchSpec> &specs, + const lldb_private::SymbolContext &sc); + void ReportSymbolLookupError(const ConstString &name); @@ -275,9 +384,6 @@ private: void registerEHFrames(uint8_t *Addr, uint64_t LoadAddr, size_t Size) override { } - //------------------------------------------------------------------ - /// Passthrough interface stub - //------------------------------------------------------------------ uint64_t getSymbolAddress(const std::string &Name) override; void *getPointerToNamedFunction(const std::string &Name, @@ -288,45 +394,6 @@ private: IRExecutionUnit &m_parent; ///< The execution unit this is a proxy for. }; - //---------------------------------------------------------------------- - /// @class JittedFunction IRExecutionUnit.h "lldb/Expression/IRExecutionUnit.h" - /// @brief Encapsulates a single function that has been generated by the JIT. - /// - /// Functions that have been generated by the JIT are first resident in the - /// local process, and then placed in the target process. JittedFunction - /// represents a function possibly resident in both. - //---------------------------------------------------------------------- - struct JittedFunction { - std::string m_name; ///< The function's name - lldb::addr_t m_local_addr; ///< The address of the function in LLDB's memory - lldb::addr_t m_remote_addr; ///< The address of the function in the target's memory - - //------------------------------------------------------------------ - /// Constructor - /// - /// Initializes class variables. - /// - /// @param[in] name - /// The name of the function. - /// - /// @param[in] local_addr - /// The address of the function in LLDB, or LLDB_INVALID_ADDRESS if - /// it is not present in LLDB's memory. - /// - /// @param[in] remote_addr - /// The address of the function in the target, or LLDB_INVALID_ADDRESS - /// if it is not present in the target's memory. - //------------------------------------------------------------------ - JittedFunction (const char *name, - lldb::addr_t local_addr = LLDB_INVALID_ADDRESS, - lldb::addr_t remote_addr = LLDB_INVALID_ADDRESS) : - m_name (name), - m_local_addr (local_addr), - m_remote_addr (remote_addr) - { - } - }; - static const unsigned eSectionIDInvalid = (unsigned)-1; //---------------------------------------------------------------------- @@ -377,6 +444,9 @@ private: void dump (Log *log); }; + bool + CommitOneAllocation (lldb::ProcessSP &process_sp, Error &error, AllocationRecord &record); + typedef std::vector<AllocationRecord> RecordVector; RecordVector m_records; @@ -385,14 +455,24 @@ private: std::unique_ptr<llvm::Module> m_module_ap; ///< Holder for the module until it's been handed off llvm::Module *m_module; ///< Owned by the execution engine std::vector<std::string> m_cpu_features; - llvm::SmallVector<JittedFunction, 1> m_jitted_functions; ///< A vector of all functions that have been JITted into machine code + std::vector<JittedFunction> m_jitted_functions; ///< A vector of all functions that have been JITted into machine code + std::vector<JittedGlobalVariable> m_jitted_global_variables; ///< A vector of all functions that have been JITted into machine code const ConstString m_name; + SymbolContext m_sym_ctx; ///< Used for symbol lookups std::vector<ConstString> m_failed_lookups; std::atomic<bool> m_did_jit; lldb::addr_t m_function_load_addr; lldb::addr_t m_function_end_load_addr; + + bool m_strip_underscore; ///< True for platforms where global symbols have a _ prefix + bool m_reported_allocations; ///< True after allocations have been reported. It is possible that + ///< sections will be allocated when this is true, in which case they weren't + ///< depended on by any function. (Top-level code defining a variable, but + ///< defining no functions using that variable, would do this.) If this + ///< is true, any allocations need to be committed immediately -- no + ///< opportunity for relocation. }; } // namespace lldb_private diff --git a/include/lldb/Expression/IRInterpreter.h b/include/lldb/Expression/IRInterpreter.h index 4eb81bc68d19..14c145b91c26 100644 --- a/include/lldb/Expression/IRInterpreter.h +++ b/include/lldb/Expression/IRInterpreter.h @@ -50,7 +50,7 @@ public: Interpret (llvm::Module &module, llvm::Function &function, llvm::ArrayRef<lldb::addr_t> args, - lldb_private::IRMemoryMap &memory_map, + lldb_private::IRExecutionUnit &execution_unit, lldb_private::Error &error, lldb::addr_t stack_frame_bottom, lldb::addr_t stack_frame_top, diff --git a/include/lldb/Expression/IRMemoryMap.h b/include/lldb/Expression/IRMemoryMap.h index 6fb718a341f7..36631d25a742 100644 --- a/include/lldb/Expression/IRMemoryMap.h +++ b/include/lldb/Expression/IRMemoryMap.h @@ -129,7 +129,7 @@ private: typedef std::map<lldb::addr_t, Allocation> AllocationMap; AllocationMap m_allocations; - lldb::addr_t FindSpace (size_t size, bool zero_memory = false); + lldb::addr_t FindSpace (size_t size); bool ContainsHostOnlyAllocations (); AllocationMap::iterator FindAllocation (lldb::addr_t addr, size_t size); diff --git a/include/lldb/Expression/LLVMUserExpression.h b/include/lldb/Expression/LLVMUserExpression.h index e3d17986f4b3..3762fa11ddbd 100644 --- a/include/lldb/Expression/LLVMUserExpression.h +++ b/include/lldb/Expression/LLVMUserExpression.h @@ -16,6 +16,9 @@ #include <map> #include <vector> +// Other libraries and framework includes +#include "llvm/IR/LegacyPassManager.h" + // Project includes #include "lldb/Expression/UserExpression.h" @@ -34,26 +37,28 @@ namespace lldb_private //---------------------------------------------------------------------- class LLVMUserExpression : public UserExpression { - public: - LLVMUserExpression(ExecutionContextScope &exe_scope, - const char *expr, - const char *expr_prefix, - lldb::LanguageType language, - ResultType desired_type, +public: + // The IRPasses struct is filled in by a runtime after an expression is compiled and can be used to to run + // fixups/analysis passes as required. EarlyPasses are run on the generated module before lldb runs its own IR + // fixups and inserts instrumentation code/pointer checks. LatePasses are run after the module has been processed by + // llvm, before the module is assembled and run in the ThreadPlan. + struct IRPasses + { + IRPasses() : EarlyPasses(nullptr), LatePasses(nullptr){}; + std::shared_ptr<llvm::legacy::PassManager> EarlyPasses; + std::shared_ptr<llvm::legacy::PassManager> LatePasses; + }; + + LLVMUserExpression(ExecutionContextScope &exe_scope, const char *expr, const char *expr_prefix, + lldb::LanguageType language, ResultType desired_type, const EvaluateExpressionOptions &options); ~LLVMUserExpression() override; - lldb::ExpressionResults Execute(Stream &error_stream, - ExecutionContext &exe_ctx, - const EvaluateExpressionOptions &options, - lldb::UserExpressionSP &shared_ptr_to_me, - lldb::ExpressionVariableSP &result) override; - - bool FinalizeJITExecution(Stream &error_stream, - ExecutionContext &exe_ctx, - lldb::ExpressionVariableSP &result, - lldb::addr_t function_stack_bottom = LLDB_INVALID_ADDRESS, - lldb::addr_t function_stack_top = LLDB_INVALID_ADDRESS) override; + bool + FinalizeJITExecution(DiagnosticManager &diagnostic_manager, ExecutionContext &exe_ctx, + lldb::ExpressionVariableSP &result, + lldb::addr_t function_stack_bottom = LLDB_INVALID_ADDRESS, + lldb::addr_t function_stack_top = LLDB_INVALID_ADDRESS) override; bool CanInterpret() override @@ -73,17 +78,22 @@ class LLVMUserExpression : public UserExpression lldb::ModuleSP GetJITModule() override; - protected: - virtual void ScanContext(ExecutionContext &exe_ctx, lldb_private::Error &err) = 0; +protected: + lldb::ExpressionResults + DoExecute(DiagnosticManager &diagnostic_manager, ExecutionContext &exe_ctx, + const EvaluateExpressionOptions &options, lldb::UserExpressionSP &shared_ptr_to_me, + lldb::ExpressionVariableSP &result) override; - bool PrepareToExecuteJITExpression(Stream &error_stream, ExecutionContext &exe_ctx, lldb::addr_t &struct_address); + virtual void + ScanContext(ExecutionContext &exe_ctx, lldb_private::Error &err) = 0; - virtual bool - AddArguments (ExecutionContext &exe_ctx, - std::vector<lldb::addr_t> &args, - lldb::addr_t struct_address, - Stream &error_stream) = 0; + bool + PrepareToExecuteJITExpression(DiagnosticManager &diagnostic_manager, ExecutionContext &exe_ctx, + lldb::addr_t &struct_address); + virtual bool + AddArguments(ExecutionContext &exe_ctx, std::vector<lldb::addr_t> &args, lldb::addr_t struct_address, + DiagnosticManager &diagnostic_manager) = 0; lldb::addr_t m_stack_frame_bottom; ///< The bottom of the allocated stack frame. lldb::addr_t m_stack_frame_top; ///< The top of the allocated stack frame. diff --git a/include/lldb/Expression/UserExpression.h b/include/lldb/Expression/UserExpression.h index 517dfcd1dc47..2b685dc046c7 100644 --- a/include/lldb/Expression/UserExpression.h +++ b/include/lldb/Expression/UserExpression.h @@ -79,8 +79,8 @@ public: //------------------------------------------------------------------ /// Parse the expression /// - /// @param[in] error_stream - /// A stream to print parse errors and warnings to. + /// @param[in] diagnostic_manager + /// A diagnostic manager to report parse errors and warnings to. /// /// @param[in] exe_ctx /// The execution context to use when looking up entities that @@ -98,11 +98,8 @@ public: /// True on success (no errors); false otherwise. //------------------------------------------------------------------ virtual bool - Parse (Stream &error_stream, - ExecutionContext &exe_ctx, - lldb_private::ExecutionPolicy execution_policy, - bool keep_result_in_memory, - bool generate_debug_info) = 0; + Parse(DiagnosticManager &diagnostic_manager, ExecutionContext &exe_ctx, + lldb_private::ExecutionPolicy execution_policy, bool keep_result_in_memory, bool generate_debug_info) = 0; virtual bool CanInterpret() = 0; @@ -110,10 +107,11 @@ public: MatchesContext (ExecutionContext &exe_ctx); //------------------------------------------------------------------ - /// Execute the parsed expression + /// Execute the parsed expression by callinng the derived class's + /// DoExecute method. /// - /// @param[in] error_stream - /// A stream to print errors to. + /// @param[in] diagnostic_manager + /// A diagnostic manager to report errors to. /// /// @param[in] exe_ctx /// The execution context to use when looking up entities that @@ -136,16 +134,15 @@ public: /// @return /// A Process::Execution results value. //------------------------------------------------------------------ - virtual lldb::ExpressionResults Execute(Stream &error_stream, ExecutionContext &exe_ctx, - const EvaluateExpressionOptions &options, - lldb::UserExpressionSP &shared_ptr_to_me, - lldb::ExpressionVariableSP &result) = 0; + lldb::ExpressionResults + Execute(DiagnosticManager &diagnostic_manager, ExecutionContext &exe_ctx, const EvaluateExpressionOptions &options, + lldb::UserExpressionSP &shared_ptr_to_me, lldb::ExpressionVariableSP &result); //------------------------------------------------------------------ /// Apply the side effects of the function to program state. /// - /// @param[in] error_stream - /// A stream to print errors to. + /// @param[in] diagnostic_manager + /// A diagnostic manager to report errors to. /// /// @param[in] exe_ctx /// The execution context to use when looking up entities that @@ -164,10 +161,10 @@ public: /// @return /// A Process::Execution results value. //------------------------------------------------------------------ - virtual bool FinalizeJITExecution(Stream &error_stream, ExecutionContext &exe_ctx, - lldb::ExpressionVariableSP &result, - lldb::addr_t function_stack_bottom = LLDB_INVALID_ADDRESS, - lldb::addr_t function_stack_top = LLDB_INVALID_ADDRESS) = 0; + virtual bool + FinalizeJITExecution(DiagnosticManager &diagnostic_manager, ExecutionContext &exe_ctx, + lldb::ExpressionVariableSP &result, lldb::addr_t function_stack_bottom = LLDB_INVALID_ADDRESS, + lldb::addr_t function_stack_top = LLDB_INVALID_ADDRESS) = 0; //------------------------------------------------------------------ /// Return the string that the parser should parse. @@ -285,6 +282,9 @@ public: /// @param[in] line_offset /// The offset of the first line of the expression from the "beginning" of a virtual source file used for error reporting and debug info. /// + /// @param[out] fixed_expression + /// If non-nullptr, the fixed expression is copied into the provided string. + /// /// @param[out] jit_module_sp_ptr /// If non-nullptr, used to persist the generated IR module. /// @@ -299,11 +299,24 @@ public: lldb::ValueObjectSP &result_valobj_sp, Error &error, uint32_t line_offset = 0, + std::string *fixed_expression = nullptr, lldb::ModuleSP *jit_module_sp_ptr = nullptr); static const Error::ValueType kNoResult = 0x1001; ///< ValueObject::GetError() returns this if there is no result from the expression. + + const char * + GetFixedText() + { + if (m_fixed_text.empty()) + return nullptr; + return m_fixed_text.c_str(); + } protected: + virtual lldb::ExpressionResults + DoExecute(DiagnosticManager &diagnostic_manager, ExecutionContext &exe_ctx, const EvaluateExpressionOptions &options, + lldb::UserExpressionSP &shared_ptr_to_me, lldb::ExpressionVariableSP &result) = 0; + static lldb::addr_t GetObjectPointer (lldb::StackFrameSP frame_sp, ConstString &object_name, @@ -325,6 +338,7 @@ protected: Address m_address; ///< The address the process is stopped in. std::string m_expr_text; ///< The text of the expression, as typed by the user std::string m_expr_prefix; ///< The text of the translation-level definitions, as provided by the user + std::string m_fixed_text; ///< The text of the expression with fix-its applied - this won't be set if the fixed text doesn't parse. lldb::LanguageType m_language; ///< The language to use when parsing (eLanguageTypeUnknown means use defaults) ResultType m_desired_type; ///< The type to coerce the expression's result to. If eResultTypeAny, inferred from the expression. EvaluateExpressionOptions m_options; ///< Additional options provided by the user. diff --git a/include/lldb/Expression/UtilityFunction.h b/include/lldb/Expression/UtilityFunction.h index bee83d8111e4..a78972082c52 100644 --- a/include/lldb/Expression/UtilityFunction.h +++ b/include/lldb/Expression/UtilityFunction.h @@ -54,8 +54,8 @@ public: //------------------------------------------------------------------ /// Install the utility function into a process /// - /// @param[in] error_stream - /// A stream to print parse errors and warnings to. + /// @param[in] diagnostic_manager + /// A diagnostic manager to print parse errors and warnings to. /// /// @param[in] exe_ctx /// The execution context to install the utility function to. @@ -64,8 +64,8 @@ public: /// True on success (no errors); false otherwise. //------------------------------------------------------------------ virtual bool - Install (Stream &error_stream, ExecutionContext &exe_ctx) = 0; - + Install(DiagnosticManager &diagnostic_manager, ExecutionContext &exe_ctx) = 0; + //------------------------------------------------------------------ /// Check whether the given PC is inside the function /// @@ -139,8 +139,10 @@ public: } // This makes the function caller function. + // Pass in the ThreadSP if you have one available, compilation can end up calling code (e.g. to look up indirect + // functions) and we don't want this to wander onto another thread. FunctionCaller * - MakeFunctionCaller(const CompilerType &return_type, const ValueList &arg_value_list, Error &error); + MakeFunctionCaller(const CompilerType &return_type, const ValueList &arg_value_list, lldb::ThreadSP compilation_thread, Error &error); // This one retrieves the function caller that is already made. If you haven't made it yet, this returns nullptr FunctionCaller * diff --git a/include/lldb/Host/Editline.h b/include/lldb/Host/Editline.h index 697be4cd8e77..43c0eccf37dd 100644 --- a/include/lldb/Host/Editline.h +++ b/include/lldb/Host/Editline.h @@ -27,11 +27,12 @@ #include <sstream> #include <vector> +#include <locale> // components needed to handle wide characters ( <codecvt>, codecvt_utf8, libedit built with '--enable-widec' ) -// are not consistenly available on non-OSX platforms. The wchar_t versions of libedit functions will only be +// are available on some platforms. The wchar_t versions of libedit functions will only be // used in cases where this is true. This is a compile time dependecy, for now selected per target Platform -#if defined (__APPLE__) +#if defined (__APPLE__) || defined(__NetBSD__) #define LLDB_EDITLINE_USE_WCHAR 1 #include <codecvt> #else @@ -49,13 +50,13 @@ #endif #endif +#include <mutex> #include <string> #include <vector> #include "lldb/Host/Condition.h" #include "lldb/Host/ConnectionFileDescriptor.h" #include "lldb/Host/FileSpec.h" -#include "lldb/Host/Mutex.h" #include "lldb/Host/Predicate.h" namespace lldb_private { @@ -278,11 +279,15 @@ namespace lldb_private { /// Prompt implementation for EditLine. const char * Prompt(); - - /// Line break command used when return is pressed in multi-line mode. + + /// Line break command used when meta+return is pressed in multi-line mode. unsigned char BreakLineCommand (int ch); - + + /// Command used when return is pressed in multi-line mode. + unsigned char + EndOrAddLineCommand(int ch); + /// Delete command used when delete is pressed in multi-line mode. unsigned char DeleteNextCharCommand (int ch); @@ -298,7 +303,15 @@ namespace lldb_private { /// Line navigation command used when ^N or down arrow are pressed in multi-line mode. unsigned char NextLineCommand (int ch); - + + /// History navigation command used when Alt + up arrow is pressed in multi-line mode. + unsigned char + PreviousHistoryCommand(int ch); + + /// History navigation command used when Alt + down arrow is pressed in multi-line mode. + unsigned char + NextHistoryCommand(int ch); + /// Buffer start command used when Esc < is typed in multi-line emacs mode. unsigned char BufferStartCommand (int ch); @@ -358,7 +371,7 @@ namespace lldb_private { CompleteCallbackType m_completion_callback = nullptr; void * m_completion_callback_baton = nullptr; - Mutex m_output_mutex; + std::mutex m_output_mutex; }; } diff --git a/include/lldb/Host/File.h b/include/lldb/Host/File.h index 27f3f405ffd3..e2c44fa5c0d2 100644 --- a/include/lldb/Host/File.h +++ b/include/lldb/Host/File.h @@ -45,7 +45,7 @@ public: eOpenOptionNonBlocking = (1u << 4), // File reads eOpenOptionCanCreate = (1u << 5), // Create file if doesn't already exist eOpenOptionCanCreateNewOnly = (1u << 6), // Can create file only if it doesn't already exist - eOpenoptionDontFollowSymlinks = (1u << 7), + eOpenOptionDontFollowSymlinks = (1u << 7), eOpenOptionCloseOnExec = (1u << 8) // Close the file when executing a new process }; @@ -74,8 +74,6 @@ public: { } - File (const File &rhs); - //------------------------------------------------------------------ /// Constructor with path. /// @@ -138,9 +136,6 @@ public: //------------------------------------------------------------------ ~File() override; - File & - operator= (const File &rhs); - bool IsValid() const override { @@ -223,9 +218,9 @@ public: Error Close() override; - Error - Duplicate (const File &rhs); - + void + Clear (); + int GetDescriptor() const; @@ -554,6 +549,9 @@ protected: LazyBool m_is_interactive; LazyBool m_is_real_terminal; LazyBool m_supports_colors; + +private: + DISALLOW_COPY_AND_ASSIGN(File); }; } // namespace lldb_private diff --git a/include/lldb/Host/FileSpec.h b/include/lldb/Host/FileSpec.h index 0ff1bc9d2f44..219af662dfcb 100644 --- a/include/lldb/Host/FileSpec.h +++ b/include/lldb/Host/FileSpec.h @@ -117,6 +117,12 @@ public: //------------------------------------------------------------------ ~FileSpec (); + bool + DirectoryEquals(const FileSpec &other) const; + + bool + FileEquals(const FileSpec &other) const; + //------------------------------------------------------------------ /// Assignment operator. /// @@ -261,6 +267,19 @@ public: Equal (const FileSpec& a, const FileSpec& b, bool full, bool remove_backups = false); //------------------------------------------------------------------ + /// Case sensitivity of path. + /// + /// @return + /// \b true if the file path is case sensitive (POSIX), false + /// if case insensitive (Windows). + //------------------------------------------------------------------ + bool + IsCaseSensitive() const + { + return m_syntax != ePathSyntaxWindows; + } + + //------------------------------------------------------------------ /// Dump this object to a Stream. /// /// Dump the object to the supplied stream \a s. If the object diff --git a/include/lldb/Host/FileSystem.h b/include/lldb/Host/FileSystem.h index 465ad451bdd6..d656d2264f66 100644 --- a/include/lldb/Host/FileSystem.h +++ b/include/lldb/Host/FileSystem.h @@ -11,6 +11,8 @@ #define liblldb_Host_FileSystem_h #include <stdint.h> +#include <stdio.h> +#include <sys/stat.h> #include "lldb/lldb-types.h" @@ -23,6 +25,7 @@ class FileSystem { public: static const char *DEV_NULL; + static const char *PATH_CONVERSION_ERROR; static FileSpec::PathSyntax GetNativePathSyntax(); @@ -59,6 +62,15 @@ class FileSystem /// Return \b true if \a spec is on a locally mounted file system, \b false otherwise. static bool IsLocal(const FileSpec &spec); + + /// Wraps ::fopen in a platform-independent way. Once opened, FILEs can be + /// manipulated and closed with the normal ::fread, ::fclose, etc. functions. + static FILE * + Fopen(const char *path, const char *mode); + + /// Wraps ::stat in a platform-independent way. + static int + Stat(const char *path, struct stat *stats); }; } diff --git a/include/lldb/Host/Host.h b/include/lldb/Host/Host.h index 235367a7cc5c..6a6b2265257a 100644 --- a/include/lldb/Host/Host.h +++ b/include/lldb/Host/Host.h @@ -38,12 +38,10 @@ class ProcessLaunchInfo; class Host { public: - - typedef bool (*MonitorChildProcessCallback) (void *callback_baton, - lldb::pid_t pid, - bool exited, - int signal, // Zero for no signal - int status); // Exit value of process if signal is zero + typedef std::function<bool(lldb::pid_t pid, bool exited, + int signal, // Zero for no signal + int status)> // Exit value of process if signal is zero + MonitorChildProcessCallback; //------------------------------------------------------------------ /// Start monitoring a child process. @@ -65,10 +63,6 @@ public: /// A function callback to call when a child receives a signal /// (if \a monitor_signals is true) or a child exits. /// - /// @param[in] callback_baton - /// A void * of user data that will be pass back when - /// \a callback is called. - /// /// @param[in] pid /// The process ID of a child process to monitor, -1 for all /// processes. @@ -84,8 +78,8 @@ public: /// /// @see static void Host::StopMonitoringChildProcess (uint32_t) //------------------------------------------------------------------ - static HostThread StartMonitoringChildProcess(MonitorChildProcessCallback callback, void *callback_baton, lldb::pid_t pid, - bool monitor_signals); + static HostThread + StartMonitoringChildProcess(const MonitorChildProcessCallback &callback, lldb::pid_t pid, bool monitor_signals); enum SystemLogType { diff --git a/include/lldb/Host/HostInfoBase.h b/include/lldb/Host/HostInfoBase.h index 6a5f784ebba3..654c9683286b 100644 --- a/include/lldb/Host/HostInfoBase.h +++ b/include/lldb/Host/HostInfoBase.h @@ -34,6 +34,8 @@ class HostInfoBase public: static void Initialize(); + static void + Terminate(); //------------------------------------------------------------------ /// Returns the number of CPUs on this current host. diff --git a/include/lldb/Host/HostNativeProcessBase.h b/include/lldb/Host/HostNativeProcessBase.h index ba16bf2b876f..d51161f1ef1b 100644 --- a/include/lldb/Host/HostNativeProcessBase.h +++ b/include/lldb/Host/HostNativeProcessBase.h @@ -46,9 +46,10 @@ class HostNativeProcessBase return m_process; } - virtual HostThread StartMonitoring(HostProcess::MonitorCallback callback, void *callback_baton, bool monitor_signals) = 0; + virtual HostThread + StartMonitoring(const Host::MonitorChildProcessCallback &callback, bool monitor_signals) = 0; - protected: +protected: lldb::process_t m_process; }; diff --git a/include/lldb/Host/HostProcess.h b/include/lldb/Host/HostProcess.h index aff779aee219..59585fc31130 100644 --- a/include/lldb/Host/HostProcess.h +++ b/include/lldb/Host/HostProcess.h @@ -10,6 +10,7 @@ #ifndef lldb_Host_HostProcess_h_ #define lldb_Host_HostProcess_h_ +#include "lldb/Host/Host.h" #include "lldb/lldb-types.h" //---------------------------------------------------------------------- @@ -36,9 +37,7 @@ class HostThread; class HostProcess { - public: - typedef bool (*MonitorCallback)(void *callback_baton, lldb::pid_t process, bool exited, int signal, int status); - +public: HostProcess(); HostProcess(lldb::process_t process); ~HostProcess(); @@ -49,7 +48,8 @@ class HostProcess lldb::pid_t GetProcessId() const; bool IsRunning() const; - HostThread StartMonitoring(MonitorCallback callback, void *callback_baton, bool monitor_signals); + HostThread + StartMonitoring(const Host::MonitorChildProcessCallback &callback, bool monitor_signals); HostNativeProcessBase &GetNativeProcess(); const HostNativeProcessBase &GetNativeProcess() const; diff --git a/include/lldb/Host/OptionParser.h b/include/lldb/Host/OptionParser.h index 175a1973c7af..c2aeaf0430ea 100644 --- a/include/lldb/Host/OptionParser.h +++ b/include/lldb/Host/OptionParser.h @@ -10,8 +10,8 @@ #ifndef liblldb_OptionParser_h_ #define liblldb_OptionParser_h_ +#include <mutex> #include <string> -#include "lldb/Host/Mutex.h" struct option; @@ -39,7 +39,8 @@ public: eOptionalArgument }; - static void Prepare(Mutex::Locker &locker); + static void + Prepare(std::unique_lock<std::mutex> &lock); static void EnableError(bool error); diff --git a/include/lldb/Host/ProcessRunLock.h b/include/lldb/Host/ProcessRunLock.h index ceb1e90be757..797939a7edee 100644 --- a/include/lldb/Host/ProcessRunLock.h +++ b/include/lldb/Host/ProcessRunLock.h @@ -18,7 +18,6 @@ // Other libraries and framework includes // Project includes #include "lldb/lldb-defines.h" -#include "lldb/Host/Mutex.h" #include "lldb/Host/Condition.h" //---------------------------------------------------------------------- diff --git a/include/lldb/Host/common/NativeBreakpointList.h b/include/lldb/Host/common/NativeBreakpointList.h index aba2f8a74cdc..bd1a9ae09db2 100644 --- a/include/lldb/Host/common/NativeBreakpointList.h +++ b/include/lldb/Host/common/NativeBreakpointList.h @@ -12,11 +12,11 @@ #include "lldb/lldb-private-forward.h" #include "lldb/Core/Error.h" -#include "lldb/Host/Mutex.h" // #include "lldb/Host/NativeBreakpoint.h" #include <functional> #include <map> +#include <mutex> namespace lldb_private { @@ -48,7 +48,7 @@ namespace lldb_private private: typedef std::map<lldb::addr_t, NativeBreakpointSP> BreakpointMap; - Mutex m_mutex; + std::recursive_mutex m_mutex; BreakpointMap m_breakpoints; }; } diff --git a/include/lldb/Host/common/NativeProcessProtocol.h b/include/lldb/Host/common/NativeProcessProtocol.h index 7236bf659042..d306a58f3cab 100644 --- a/include/lldb/Host/common/NativeProcessProtocol.h +++ b/include/lldb/Host/common/NativeProcessProtocol.h @@ -10,12 +10,12 @@ #ifndef liblldb_NativeProcessProtocol_h_ #define liblldb_NativeProcessProtocol_h_ +#include <mutex> #include <vector> #include "lldb/lldb-private-forward.h" #include "lldb/lldb-types.h" #include "lldb/Core/Error.h" -#include "lldb/Host/Mutex.h" #include "lldb/Host/MainLoop.h" #include "llvm/ADT/StringRef.h" @@ -364,15 +364,15 @@ namespace lldb_private std::vector<NativeThreadProtocolSP> m_threads; lldb::tid_t m_current_thread_id; - mutable Mutex m_threads_mutex; + mutable std::recursive_mutex m_threads_mutex; lldb::StateType m_state; - mutable Mutex m_state_mutex; + mutable std::recursive_mutex m_state_mutex; lldb_private::ExitType m_exit_type; int m_exit_status; std::string m_exit_description; - Mutex m_delegates_mutex; + std::recursive_mutex m_delegates_mutex; std::vector<NativeDelegate*> m_delegates; NativeBreakpointList m_breakpoint_list; NativeWatchpointList m_watchpoint_list; diff --git a/include/lldb/Host/linux/Signalfd.h b/include/lldb/Host/linux/Signalfd.h deleted file mode 100644 index cf50e87097fb..000000000000 --- a/include/lldb/Host/linux/Signalfd.h +++ /dev/null @@ -1,54 +0,0 @@ -//===-- Signalfd.h ----------------------------------------------*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// - -// This file defines signalfd functions & structures - -#ifndef liblldb_Host_linux_Signalfd_h_ -#define liblldb_Host_linux_Signalfd_h_ - -#ifdef __ANDROID_NDK__ -#include <android/api-level.h> -#endif - -#if defined(__ANDROID_API__) && __ANDROID_API__ < 21 - -#include <linux/types.h> -#include <linux/fcntl.h> - -#define SFD_CLOEXEC O_CLOEXEC -#define SFD_NONBLOCK O_NONBLOCK - -struct signalfd_siginfo { - __u32 ssi_signo; - __s32 ssi_errno; - __s32 ssi_code; - __u32 ssi_pid; - __u32 ssi_uid; - __s32 ssi_fd; - __u32 ssi_tid; - __u32 ssi_band; - __u32 ssi_overrun; - __u32 ssi_trapno; - __s32 ssi_status; - __s32 ssi_int; - __u64 ssi_ptr; - __u64 ssi_utime; - __u64 ssi_stime; - __u64 ssi_addr; - __u16 ssi_addr_lsb; - __u8 __pad[46]; -}; - -int signalfd (int fd, const sigset_t *mask, int flags); - -#else -#include <sys/signalfd.h> -#endif - -#endif // liblldb_Host_linux_Signalfd_h_ diff --git a/include/lldb/Host/macosx/HostInfoMacOSX.h b/include/lldb/Host/macosx/HostInfoMacOSX.h index 3b62c7fb9061..4a8ee4fd850e 100644 --- a/include/lldb/Host/macosx/HostInfoMacOSX.h +++ b/include/lldb/Host/macosx/HostInfoMacOSX.h @@ -32,6 +32,7 @@ class HostInfoMacOSX : public HostInfoPosix static bool GetOSBuildString(std::string &s); static bool GetOSKernelDescription(std::string &s); static FileSpec GetProgramFileSpec(); + static uint32_t GetMaxThreadNameLength(); protected: static bool ComputeSupportExeDirectory(FileSpec &file_spec); diff --git a/include/lldb/Host/posix/ConnectionFileDescriptorPosix.h b/include/lldb/Host/posix/ConnectionFileDescriptorPosix.h index 7e7904cd5fa8..0d3ec35ce467 100644 --- a/include/lldb/Host/posix/ConnectionFileDescriptorPosix.h +++ b/include/lldb/Host/posix/ConnectionFileDescriptorPosix.h @@ -13,13 +13,13 @@ // C++ Includes #include <atomic> #include <memory> +#include <mutex> #include "lldb/lldb-forward.h" // Other libraries and framework includes // Project includes #include "lldb/Core/Connection.h" -#include "lldb/Host/Mutex.h" #include "lldb/Host/Pipe.h" #include "lldb/Host/Predicate.h" #include "lldb/Host/IOObject.h" @@ -105,7 +105,7 @@ class ConnectionFileDescriptor : public Connection // the port number. Pipe m_pipe; - Mutex m_mutex; + std::recursive_mutex m_mutex; std::atomic<bool> m_shutting_down; // This marks that we are shutting down so if we get woken up from // BytesAvailable to disconnect, we won't try to read again. bool m_waiting_for_accept; diff --git a/include/lldb/Host/posix/HostInfoPosix.h b/include/lldb/Host/posix/HostInfoPosix.h index 9524a2a2481d..2e6c2a22f99c 100644 --- a/include/lldb/Host/posix/HostInfoPosix.h +++ b/include/lldb/Host/posix/HostInfoPosix.h @@ -33,7 +33,10 @@ class HostInfoPosix : public HostInfoBase static FileSpec GetDefaultShell(); - protected: + static bool + GetEnvironmentVar(const std::string &var_name, std::string &var); + +protected: static bool ComputeSupportExeDirectory(FileSpec &file_spec); static bool ComputeHeaderDirectory(FileSpec &file_spec); static bool ComputePythonDirectory(FileSpec &file_spec); diff --git a/include/lldb/Host/posix/HostProcessPosix.h b/include/lldb/Host/posix/HostProcessPosix.h index 5db49d17d757..53700fda1acc 100644 --- a/include/lldb/Host/posix/HostProcessPosix.h +++ b/include/lldb/Host/posix/HostProcessPosix.h @@ -39,7 +39,8 @@ class HostProcessPosix : public HostNativeProcessBase lldb::pid_t GetProcessId() const override; bool IsRunning() const override; - HostThread StartMonitoring(HostProcess::MonitorCallback callback, void *callback_baton, bool monitor_signals) override; + HostThread + StartMonitoring(const Host::MonitorChildProcessCallback &callback, bool monitor_signals) override; }; } // namespace lldb_private diff --git a/include/lldb/Host/windows/HostInfoWindows.h b/include/lldb/Host/windows/HostInfoWindows.h index 022e15533d31..23d52e7810e7 100644 --- a/include/lldb/Host/windows/HostInfoWindows.h +++ b/include/lldb/Host/windows/HostInfoWindows.h @@ -26,14 +26,29 @@ class HostInfoWindows : public HostInfoBase ~HostInfoWindows(); public: - static size_t GetPageSize(); - - static bool GetOSVersion(uint32_t &major, uint32_t &minor, uint32_t &update); - static bool GetOSBuildString(std::string &s); - static bool GetOSKernelDescription(std::string &s); - static bool GetHostname(std::string &s); - static FileSpec GetProgramFileSpec(); - static FileSpec GetDefaultShell(); + static void + Initialize(); + static void + Terminate(); + + static size_t + GetPageSize(); + + static bool + GetOSVersion(uint32_t &major, uint32_t &minor, uint32_t &update); + static bool + GetOSBuildString(std::string &s); + static bool + GetOSKernelDescription(std::string &s); + static bool + GetHostname(std::string &s); + static FileSpec + GetProgramFileSpec(); + static FileSpec + GetDefaultShell(); + + static bool + GetEnvironmentVar(const std::string &var_name, std::string &var); protected: static bool ComputePythonDirectory(FileSpec &file_spec); diff --git a/include/lldb/Host/windows/HostProcessWindows.h b/include/lldb/Host/windows/HostProcessWindows.h index 6f8ad3dc4d40..2d2ad0e70e8d 100644 --- a/include/lldb/Host/windows/HostProcessWindows.h +++ b/include/lldb/Host/windows/HostProcessWindows.h @@ -33,9 +33,10 @@ class HostProcessWindows : public HostNativeProcessBase virtual lldb::pid_t GetProcessId() const; virtual bool IsRunning() const; - virtual HostThread StartMonitoring(HostProcess::MonitorCallback callback, void *callback_baton, bool monitor_signals); + HostThread + StartMonitoring(const Host::MonitorChildProcessCallback &callback, bool monitor_signals) override; - private: +private: static lldb::thread_result_t MonitorThread(void *thread_arg); void Close(); diff --git a/include/lldb/Initialization/SystemLifetimeManager.h b/include/lldb/Initialization/SystemLifetimeManager.h index 843ec2820677..2dd7b22c240a 100644 --- a/include/lldb/Initialization/SystemLifetimeManager.h +++ b/include/lldb/Initialization/SystemLifetimeManager.h @@ -11,9 +11,9 @@ #define LLDB_INITIALIZATION_SYSTEM_LIFETIME_MANAGER_H #include "lldb/lldb-private-types.h" -#include "lldb/Host/Mutex.h" #include <memory> +#include <mutex> namespace lldb_private { @@ -29,13 +29,14 @@ class SystemLifetimeManager void Terminate(); private: - Mutex m_mutex; - std::unique_ptr<SystemInitializer> m_initializer; - bool m_initialized; - - // Noncopyable. - SystemLifetimeManager(const SystemLifetimeManager &other) = delete; - SystemLifetimeManager &operator=(const SystemLifetimeManager &other) = delete; + std::recursive_mutex m_mutex; + std::unique_ptr<SystemInitializer> m_initializer; + bool m_initialized; + + // Noncopyable. + SystemLifetimeManager(const SystemLifetimeManager &other) = delete; + SystemLifetimeManager & + operator=(const SystemLifetimeManager &other) = delete; }; } diff --git a/include/lldb/Interpreter/Args.h b/include/lldb/Interpreter/Args.h index e79318ba5626..bd54d5d3db5d 100644 --- a/include/lldb/Interpreter/Args.h +++ b/include/lldb/Interpreter/Args.h @@ -91,14 +91,20 @@ public: ~Args(); //------------------------------------------------------------------ - /// Dump all arguments to the stream \a s. + /// Dump all entries to the stream \a s using label \a label_name. + /// + /// If label_name is nullptr, the dump operation is skipped. /// /// @param[in] s /// The stream to which to dump all arguments in the argument /// vector. + /// @param[in] label_name + /// The label_name to use as the label printed for each + /// entry of the args like so: + /// {label_name}[{index}]={value} //------------------------------------------------------------------ void - Dump (Stream *s); + Dump (Stream &s, const char *label_name = "argv") const; //------------------------------------------------------------------ /// Sets the command string contained by this object. @@ -403,7 +409,7 @@ public: StringToVersion (const char *s, uint32_t &major, uint32_t &minor, uint32_t &update); static const char * - GetShellSafeArgument (const char *unsafe_arg, std::string &safe_arg); + GetShellSafeArgument (const FileSpec& shell, const char *unsafe_arg, std::string &safe_arg); // EncodeEscapeSequences will change the textual representation of common // escape sequences like "\n" (two characters) into a single '\n'. It does @@ -432,6 +438,23 @@ public: void LongestCommonPrefix (std::string &common_prefix); + //------------------------------------------------------------------ + /// Return whether a given environment variable exists. + /// + /// This command treats Args like a list of environment variables, + /// as used in ProcessLaunchInfo. It treats each argument as + /// an {env_var_name}={value} or an {env_var_name} entry. + /// + /// @param[in] env_var_name + /// Specifies the name of the environment variable to check. + /// + /// @return + /// true if the specified env var name exists in the list in + /// either of the above-mentioned formats; otherwise, false. + //------------------------------------------------------------------ + bool + ContainsEnvironmentVariable(const char *env_var_name) const; + protected: //------------------------------------------------------------------ // Classes that inherit from Args can see and modify these diff --git a/include/lldb/Interpreter/CommandAlias.h b/include/lldb/Interpreter/CommandAlias.h new file mode 100644 index 000000000000..d48719f821ec --- /dev/null +++ b/include/lldb/Interpreter/CommandAlias.h @@ -0,0 +1,123 @@ +//===-- CommandAlias.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_CommandAlias_h_ +#define liblldb_CommandAlias_h_ + +// C Includes +// C++ Includes +#include <memory> + +// Other libraries and framework includes +// Project includes +#include "lldb/lldb-forward.h" +#include "lldb/Interpreter/Args.h" +#include "lldb/Interpreter/CommandObject.h" + +namespace lldb_private { +class CommandAlias : public CommandObject +{ +public: + typedef std::unique_ptr<CommandAlias> UniquePointer; + + CommandAlias (CommandInterpreter &interpreter, + lldb::CommandObjectSP cmd_sp, + const char *options_args, + const char *name, + const char *help = nullptr, + const char *syntax = nullptr, + uint32_t flags = 0); + + void + GetAliasExpansion (StreamString &help_string); + + bool + IsValid () + { + return m_underlying_command_sp && m_option_args_sp; + } + + explicit operator bool () + { + return IsValid(); + } + + bool + WantsRawCommandString() override; + + bool + WantsCompletion() override; + + int + HandleCompletion (Args &input, + int &cursor_index, + int &cursor_char_position, + int match_start_point, + int max_return_elements, + bool &word_complete, + StringList &matches) override; + + int + HandleArgumentCompletion (Args &input, + int &cursor_index, + int &cursor_char_position, + OptionElementVector &opt_element_vector, + int match_start_point, + int max_return_elements, + bool &word_complete, + StringList &matches) override; + + Options* + GetOptions() override; + + bool + IsAlias () override { return true; } + + bool + IsDashDashCommand () override; + + const char* + GetHelp () override; + + const char* + GetHelpLong () override; + + void + SetHelp (const char * str) override; + + void + SetHelpLong (const char * str) override; + + bool + Execute(const char *args_string, CommandReturnObject &result) override; + + lldb::CommandObjectSP GetUnderlyingCommand() { return m_underlying_command_sp; } + OptionArgVectorSP GetOptionArguments() { return m_option_args_sp; } + const char* GetOptionString() { return m_option_string.c_str(); } + + // this takes an alias - potentially nested (i.e. an alias to an alias) + // and expands it all the way to a non-alias command + std::pair<lldb::CommandObjectSP, OptionArgVectorSP> + Desugar (); + +protected: + bool + IsNestedAlias (); + +private: + lldb::CommandObjectSP m_underlying_command_sp; + std::string m_option_string; + OptionArgVectorSP m_option_args_sp ; + LazyBool m_is_dashdash_alias; + bool m_did_set_help : 1; + bool m_did_set_help_long : 1; +}; +} // namespace lldb_private + +#endif // liblldb_CommandAlias_h_ diff --git a/include/lldb/Interpreter/CommandHistory.h b/include/lldb/Interpreter/CommandHistory.h index db5db15fc1e5..ff05f6da6c32 100644 --- a/include/lldb/Interpreter/CommandHistory.h +++ b/include/lldb/Interpreter/CommandHistory.h @@ -12,6 +12,7 @@ // C Includes // C++ Includes +#include <mutex> #include <string> #include <vector> @@ -19,7 +20,6 @@ // Project includes #include "lldb/lldb-private.h" #include "lldb/Core/Stream.h" -#include "lldb/Host/Mutex.h" namespace lldb_private { @@ -66,7 +66,7 @@ private: DISALLOW_COPY_AND_ASSIGN(CommandHistory); typedef std::vector<std::string> History; - mutable Mutex m_mutex; + mutable std::recursive_mutex m_mutex; History m_history; }; diff --git a/include/lldb/Interpreter/CommandInterpreter.h b/include/lldb/Interpreter/CommandInterpreter.h index dd5c189d0ab9..4dc2c5859f45 100644 --- a/include/lldb/Interpreter/CommandInterpreter.h +++ b/include/lldb/Interpreter/CommandInterpreter.h @@ -20,6 +20,7 @@ #include "lldb/Core/Debugger.h" #include "lldb/Core/IOHandler.h" #include "lldb/Core/Log.h" +#include "lldb/Interpreter/CommandAlias.h" #include "lldb/Interpreter/CommandHistory.h" #include "lldb/Interpreter/CommandObject.h" #include "lldb/Interpreter/ScriptInterpreter.h" @@ -200,8 +201,6 @@ class CommandInterpreter : public IOHandlerDelegate { public: - typedef std::map<std::string, OptionArgVectorSP> OptionArgMap; - enum { eBroadcastBitThreadShouldExit = (1 << 0), @@ -277,10 +276,11 @@ public: bool UserCommandExists (const char *cmd); - void - AddAlias (const char *alias_name, - lldb::CommandObjectSP& command_obj_sp); - + CommandAlias* + AddAlias (const char *alias_name, + lldb::CommandObjectSP& command_obj_sp, + const char *args_string = nullptr); + // Remove a command if it is removable (python or regex command) bool RemoveCommand (const char *cmd); @@ -300,20 +300,8 @@ public: m_user_dict.clear(); } - OptionArgVectorSP - GetAliasOptions (const char *alias_name); - - bool - ProcessAliasOptionsArgs (lldb::CommandObjectSP &cmd_obj_sp, - const char *options_args, - OptionArgVectorSP &option_arg_vector_sp); - - void - RemoveAliasOptions (const char *alias_name); - - void - AddOrReplaceAliasOptions (const char *alias_name, - OptionArgVectorSP &option_arg_vector_sp); + CommandAlias* + GetAlias (const char *alias_name); CommandObject * BuildAliasResult (const char *alias_name, @@ -422,7 +410,6 @@ public: void GetAliasHelp (const char *alias_name, - const char *command_name, StreamString &help_string); void @@ -533,15 +520,13 @@ public: bool GetSynchronous (); - size_t - FindLongestCommandWord (CommandObject::CommandMap &dict); - void FindCommandsForApropos (const char *word, StringList &commands_found, StringList &commands_help, bool search_builtin_commands, - bool search_user_commands); + bool search_user_commands, + bool search_alias_commands); bool GetBatchCommandMode () { return m_batch_command_mode; } @@ -694,6 +679,12 @@ private: CommandObject * ResolveCommandImpl(std::string &command_line, CommandReturnObject &result); + void + FindCommandsForApropos (const char *word, + StringList &commands_found, + StringList &commands_help, + CommandObject::CommandMap &command_map); + Debugger &m_debugger; // The debugger session that this interpreter is associated with ExecutionContextRef m_exe_ctx_ref; // The current execution context to use when handling commands bool m_synchronous_execution; @@ -702,7 +693,6 @@ private: CommandObject::CommandMap m_command_dict; // Stores basic built-in commands (they cannot be deleted, removed or overwritten). CommandObject::CommandMap m_alias_dict; // Stores user aliases/abbreviations for commands CommandObject::CommandMap m_user_dict; // Stores user-defined commands - OptionArgMap m_alias_options; // Stores any options (with or without arguments) that go with any alias. CommandHistory m_command_history; std::string m_repeat_command; // Stores the command that will be executed for an empty command string. lldb::ScriptInterpreterSP m_script_interpreter_sp; diff --git a/include/lldb/Interpreter/CommandObject.h b/include/lldb/Interpreter/CommandObject.h index 8015fec41cd2..b5d39ce83257 100644 --- a/include/lldb/Interpreter/CommandObject.h +++ b/include/lldb/Interpreter/CommandObject.h @@ -23,11 +23,54 @@ #include "lldb/Interpreter/CommandCompletions.h" #include "lldb/Core/StringList.h" #include "lldb/Core/Flags.h" -#include "lldb/Host/Mutex.h" #include "lldb/Target/ExecutionContext.h" namespace lldb_private { +// This function really deals with CommandObjectLists, but we didn't make a +// CommandObjectList class, so I'm sticking it here. But we really should have +// such a class. Anyway, it looks up the commands in the map that match the partial +// string cmd_str, inserts the matches into matches, and returns the number added. + +template <typename ValueType> +int +AddNamesMatchingPartialString (std::map<std::string,ValueType> &in_map, const char *cmd_str, StringList &matches) +{ + int number_added = 0; + + const bool add_all = ((cmd_str == nullptr) || (cmd_str[0] == 0)); + + for (auto iter = in_map.begin(), end = in_map.end(); + iter != end; + iter++) + { + if (add_all || + (iter->first.find(cmd_str,0) == 0)) + { + ++number_added; + matches.AppendString(iter->first.c_str()); + } + } + + return number_added; +} + +template <typename ValueType> +size_t +FindLongestCommandWord (std::map<std::string,ValueType> &dict) +{ + auto end = dict.end(); + size_t max_len = 0; + + for (auto pos = dict.begin(); pos != end; ++pos) + { + size_t len = pos->first.size(); + if (max_len < len) + max_len = len; + } + return max_len; +} + class CommandObject { public: @@ -104,25 +147,19 @@ public: virtual const char * GetHelpLong (); - const char * + virtual const char * GetSyntax (); const char * GetCommandName (); - void + virtual void SetHelp (const char * str); - void - SetHelp (std::string str); - - void + virtual void SetHelpLong (const char * str); void - SetHelpLong (std::string str); - - void SetSyntax (const char *str); // override this to return true if you want to enable the user to delete @@ -131,14 +168,20 @@ public: virtual bool IsRemovable () const { return false; } - bool - IsAlias () { return m_is_alias; } + virtual bool + IsMultiwordObject () { return false; } - void - SetIsAlias (bool value) { m_is_alias = value; } + virtual CommandObjectMultiword* + GetAsMultiwordCommand () { return nullptr; } virtual bool - IsMultiwordObject () { return false; } + IsAlias () { return false; } + + // override this to return true if your command is somehow a "dash-dash" + // form of some other command (e.g. po is expr -O --); this is a powerful + // hint to the help system that one cannot pass options to this command + virtual bool + IsDashDashCommand () { return false; } virtual lldb::CommandObjectSP GetSubcommandSP(const char *sub_cmd, StringList *matches = nullptr) @@ -230,14 +273,6 @@ public: void SetCommandName (const char *name); - // This function really deals with CommandObjectLists, but we didn't make a - // CommandObjectList class, so I'm sticking it here. But we really should have - // such a class. Anyway, it looks up the commands in the map that match the partial - // string cmd_str, inserts the matches into matches, and returns the number added. - - static int - AddNamesMatchingPartialString (CommandMap &in_map, const char *cmd_str, StringList &matches); - //------------------------------------------------------------------ /// The input array contains a parsed version of the line. The insertion /// point is given by cursor_index (the index in input of the word containing @@ -340,7 +375,11 @@ public: } bool - HelpTextContainsWord (const char *search_word); + HelpTextContainsWord (const char *search_word, + bool search_short_help = true, + bool search_long_help = true, + bool search_syntax = true, + bool search_options = true); //------------------------------------------------------------------ /// The flags accessor. @@ -451,6 +490,12 @@ protected: // is present you want to prime the dummy target with entities that will be copied over to new targets. Target *GetSelectedOrDummyTarget(bool prefer_dummy = false); Target *GetDummyTarget(); + + // If a command needs to use the "current" thread, use this call. + // Command objects will have an ExecutionContext to use, and that may or may not have a thread in it. If it + // does, you should use that by default, if not, then use the ExecutionContext's target's selected thread, etc... + // This call insulates you from the details of this calculation. + Thread *GetDefaultThread(); //------------------------------------------------------------------ /// Check the command to make sure anything required by this @@ -471,12 +516,11 @@ protected: CommandInterpreter &m_interpreter; ExecutionContext m_exe_ctx; - Mutex::Locker m_api_locker; + std::unique_lock<std::recursive_mutex> m_api_locker; std::string m_cmd_name; std::string m_cmd_help_short; std::string m_cmd_help_long; std::string m_cmd_syntax; - bool m_is_alias; Flags m_flags; std::vector<CommandArgumentEntry> m_arguments; lldb::CommandOverrideCallback m_deprecated_command_override_callback; diff --git a/include/lldb/Interpreter/CommandObjectMultiword.h b/include/lldb/Interpreter/CommandObjectMultiword.h index e1ad2940c383..3b7d1868a855 100644 --- a/include/lldb/Interpreter/CommandObjectMultiword.h +++ b/include/lldb/Interpreter/CommandObjectMultiword.h @@ -41,6 +41,12 @@ public: { return true; } + + CommandObjectMultiword* + GetAsMultiwordCommand () override + { + return this; + } bool LoadSubCommand(const char *cmd_name, @@ -96,6 +102,11 @@ public: } protected: + CommandObject::CommandMap& + GetSubcommandDictionary () + { + return m_subcommand_dict; + } CommandObject::CommandMap m_subcommand_dict; bool m_can_be_removed; @@ -126,6 +137,9 @@ public: bool IsMultiwordObject() override; + CommandObjectMultiword* + GetAsMultiwordCommand () override; + void GenerateHelpText (Stream &result) override; diff --git a/include/lldb/Interpreter/OptionGroupValueObjectDisplay.h b/include/lldb/Interpreter/OptionGroupValueObjectDisplay.h index 53c8550da81e..86e4c1662e6e 100644 --- a/include/lldb/Interpreter/OptionGroupValueObjectDisplay.h +++ b/include/lldb/Interpreter/OptionGroupValueObjectDisplay.h @@ -77,6 +77,7 @@ public: uint32_t no_summary_depth; uint32_t max_depth; uint32_t ptr_depth; + uint32_t elem_count; lldb::DynamicValueType use_dynamic; }; diff --git a/include/lldb/Interpreter/ScriptInterpreter.h b/include/lldb/Interpreter/ScriptInterpreter.h index eafc03a00cca..8cfb3cea44b6 100644 --- a/include/lldb/Interpreter/ScriptInterpreter.h +++ b/include/lldb/Interpreter/ScriptInterpreter.h @@ -380,6 +380,12 @@ public: { return nullptr; } + + virtual ConstString + GetSyntheticTypeName (const StructuredData::ObjectSP &implementor) + { + return ConstString(); + } virtual bool RunScriptBasedCommand (const char* impl_function, diff --git a/include/lldb/Makefile b/include/lldb/Makefile deleted file mode 100644 index 6066298fce4a..000000000000 --- a/include/lldb/Makefile +++ /dev/null @@ -1,31 +0,0 @@ -LEVEL = ../../../.. -DIRS := - -include $(LEVEL)/Makefile.common - -install-local:: - $(Echo) Installing LLDB include files - $(Verb) $(MKDIR) $(DESTDIR)$(PROJ_includedir) - $(Verb) if test -d "$(PROJ_SRC_ROOT)/tools/lldb/include/lldb" ; then \ - cd $(PROJ_SRC_ROOT)/tools/lldb/include && \ - for hdr in `find lldb -type f '!' '(' -name '*~' \ - -o -name '.#*' -o -name '*.in' -o -name '*.txt' \ - -o -name 'Makefile' -o -name '*.td' -o -name '*.orig' ')' -print \ - | grep -v CVS | grep -v .svn | grep -v .dir` ; do \ - instdir=$(DESTDIR)`dirname "$(PROJ_includedir)/$$hdr"` ; \ - if test \! -d "$$instdir" ; then \ - $(EchoCmd) Making install directory $$instdir ; \ - $(MKDIR) $$instdir ;\ - fi ; \ - $(DataInstall) $$hdr $(DESTDIR)$(PROJ_includedir)/$$hdr ; \ - done ; \ - fi -ifneq ($(PROJ_SRC_ROOT),$(PROJ_OBJ_ROOT)) - $(Verb) if test -d "$(PROJ_OBJ_ROOT)/tools/lldb/include/lldb" ; then \ - cd $(PROJ_OBJ_ROOT)/tools/lldb/include && \ - for hdr in `find lldb -type f '!' '(' -name 'Makefile' ')' -print \ - | grep -v CVS | grep -v .tmp | grep -v .dir` ; do \ - $(DataInstall) $$hdr $(DESTDIR)$(PROJ_includedir)/$$hdr ; \ - done ; \ - fi -endif diff --git a/include/lldb/Symbol/ArmUnwindInfo.h b/include/lldb/Symbol/ArmUnwindInfo.h index b19af23744a4..8c40f19d2859 100644 --- a/include/lldb/Symbol/ArmUnwindInfo.h +++ b/include/lldb/Symbol/ArmUnwindInfo.h @@ -14,7 +14,6 @@ #include "lldb/Core/DataExtractor.h" #include "lldb/Core/RangeMap.h" -#include "lldb/Host/Mutex.h" #include "lldb/Symbol/ObjectFile.h" #include "lldb/lldb-private.h" diff --git a/include/lldb/Symbol/Block.h b/include/lldb/Symbol/Block.h index 6c0793dda80f..6dbb9c56097b 100644 --- a/include/lldb/Symbol/Block.h +++ b/include/lldb/Symbol/Block.h @@ -310,8 +310,9 @@ public: AppendBlockVariables (bool can_create, bool get_child_block_variables, bool stop_if_child_block_is_inlined_function, + const std::function<bool(Variable*)>& filter, VariableList *variable_list); - + //------------------------------------------------------------------ /// Appends the variables from this block, and optionally from all /// parent blocks, to \a variable_list. @@ -341,9 +342,10 @@ public: /// variable_list. //------------------------------------------------------------------ uint32_t - AppendVariables (bool can_create, - bool get_parent_variables, + AppendVariables (bool can_create, + bool get_parent_variables, bool stop_if_block_is_inlined_function, + const std::function<bool(Variable*)>& filter, VariableList *variable_list); //------------------------------------------------------------------ diff --git a/include/lldb/Symbol/ClangASTContext.h b/include/lldb/Symbol/ClangASTContext.h index bd3a113e6cc5..08f7b6b412dc 100644 --- a/include/lldb/Symbol/ClangASTContext.h +++ b/include/lldb/Symbol/ClangASTContext.h @@ -30,11 +30,14 @@ // Project includes #include "Plugins/ExpressionParser/Clang/ClangPersistentVariables.h" -#include "lldb/lldb-enumerations.h" #include "lldb/Core/ClangForward.h" #include "lldb/Core/ConstString.h" #include "lldb/Symbol/CompilerType.h" #include "lldb/Symbol/TypeSystem.h" +#include "lldb/lldb-enumerations.h" + +class DWARFASTParserClang; +class PDBASTParser; namespace lldb_private { @@ -61,6 +64,9 @@ public: ~ClangASTContext() override; + void + Finalize() override; + //------------------------------------------------------------------ // PluginInterface functions //------------------------------------------------------------------ @@ -127,7 +133,7 @@ public: void Clear(); - + const char * GetTargetTriple (); @@ -297,6 +303,11 @@ public: } CompilerType + CreateStructForIdentifier (const ConstString &type_name, + const std::initializer_list< std::pair < const char *, CompilerType > >& type_fields, + bool packed = false); + + CompilerType GetOrCreateStructForIdentifier (const ConstString &type_name, const std::initializer_list< std::pair < const char *, CompilerType > >& type_fields, bool packed = false); @@ -422,6 +433,11 @@ public: GetUniqueNamespaceDeclaration (const char *name, clang::DeclContext *decl_ctx); + static clang::NamespaceDecl * + GetUniqueNamespaceDeclaration (clang::ASTContext *ast, + const char *name, + clang::DeclContext *decl_ctx); + //------------------------------------------------------------------ // Function Types //------------------------------------------------------------------ @@ -465,6 +481,9 @@ public: SetFunctionParameters (clang::FunctionDecl *function_decl, clang::ParmVarDecl **params, unsigned num_params); + + CompilerType + CreateBlockPointerType (const CompilerType &function_type); //------------------------------------------------------------------ // Array Types @@ -513,7 +532,9 @@ public: // TypeSystem methods //------------------------------------------------------------------ DWARFASTParser * - GetDWARFParser () override; + GetDWARFParser() override; + PDBASTParser * + GetPDBParser(); //------------------------------------------------------------------ // ClangASTContext callbacks for external source lookups. @@ -536,12 +557,6 @@ public: //---------------------------------------------------------------------- // CompilerDecl override functions //---------------------------------------------------------------------- - lldb::VariableSP - DeclGetVariable (void *opaque_decl) override; - - void - DeclLinkToObject (void *opaque_decl, std::shared_ptr<void> object) override; - ConstString DeclGetName (void *opaque_decl) override; @@ -565,7 +580,9 @@ public: //---------------------------------------------------------------------- std::vector<CompilerDecl> - DeclContextFindDeclByName (void *opaque_decl_ctx, ConstString name) override; + DeclContextFindDeclByName (void *opaque_decl_ctx, + ConstString name, + const bool ignore_using_decls) override; bool DeclContextIsStructUnionOrClass (void *opaque_decl_ctx) override; @@ -583,16 +600,6 @@ public: ConstString *language_object_name_ptr) override; //---------------------------------------------------------------------- - // Clang specific CompilerType predicates - //---------------------------------------------------------------------- - - static bool - IsClangType (const CompilerType &ct) - { - return llvm::dyn_cast_or_null<ClangASTContext>(ct.GetTypeSystem()) != nullptr && ct.GetOpaqueQualType() != nullptr; - } - - //---------------------------------------------------------------------- // Clang specific clang::DeclContext functions //---------------------------------------------------------------------- @@ -678,8 +685,14 @@ public: IsFunctionPointerType (lldb::opaque_compiler_type_t type) override; bool - IsIntegerType (lldb::opaque_compiler_type_t type, bool &is_signed) override; + IsBlockPointerType (lldb::opaque_compiler_type_t type, CompilerType *function_pointer_type_ptr) override; + bool + IsIntegerType (lldb::opaque_compiler_type_t type, bool &is_signed) override; + + bool + IsEnumerationType (lldb::opaque_compiler_type_t type, bool &is_signed) override; + static bool IsObjCClassType (const CompilerType& type); @@ -694,7 +707,13 @@ public: bool IsPolymorphicClass (lldb::opaque_compiler_type_t type) override; - + + static bool + IsClassType(lldb::opaque_compiler_type_t type); + + static bool + IsEnumType(lldb::opaque_compiler_type_t type); + bool IsPossibleDynamicType(lldb::opaque_compiler_type_t type, CompilerType *target_type, // Can pass nullptr @@ -824,9 +843,6 @@ public: // If the current object represents a typedef type, get the underlying type CompilerType GetTypedefedType (lldb::opaque_compiler_type_t type) override; - - static CompilerType - RemoveFastQualifiers (const CompilerType& type); //---------------------------------------------------------------------- // Create related types using the current type's AST @@ -1025,18 +1041,12 @@ public: const char *name, // the full symbol name as seen in the symbol table (lldb::opaque_compiler_type_t type, "-[NString stringWithCString:]") const CompilerType &method_compiler_type, lldb::AccessType access, - bool is_artificial); + bool is_artificial, + bool is_variadic); static bool SetHasExternalStorage (lldb::opaque_compiler_type_t type, bool has_extern); - - static bool - CanImport (const CompilerType &type, lldb_private::ClangASTImporter &importer); - - static bool - Import (const CompilerType &type, lldb_private::ClangASTImporter &importer); - static bool GetHasExternalStorage (const CompilerType &type); //------------------------------------------------------------------ @@ -1139,29 +1149,6 @@ public: static clang::ObjCInterfaceDecl * GetAsObjCInterfaceDecl (const CompilerType& type); - - static clang::QualType - GetQualType (const CompilerType& type) - { - // Make sure we have a clang type before making a clang::QualType - if (type.GetOpaqueQualType()) - { - ClangASTContext *ast = llvm::dyn_cast_or_null<ClangASTContext>(type.GetTypeSystem()); - if (ast) - return clang::QualType::getFromOpaquePtr(type.GetOpaqueQualType()); - } - return clang::QualType(); - } - - static clang::QualType - GetCanonicalQualType (const CompilerType& type) - { - // Make sure we have a clang type before making a clang::QualType - ClangASTContext *ast = llvm::dyn_cast_or_null<ClangASTContext>(type.GetTypeSystem()); - if (ast) - return clang::QualType::getFromOpaquePtr(type.GetOpaqueQualType()).getCanonicalType(); - return clang::QualType(); - } clang::ClassTemplateDecl * ParseClassTemplateDecl (clang::DeclContext *decl_ctx, @@ -1182,26 +1169,30 @@ public: clang::VarDecl * CreateVariableDeclaration (clang::DeclContext *decl_context, const char *name, clang::QualType type); -protected: + static lldb::opaque_compiler_type_t + GetOpaqueCompilerType(clang::ASTContext *ast, lldb::BasicType basic_type); + static clang::QualType - GetQualType (lldb::opaque_compiler_type_t type) + GetQualType(lldb::opaque_compiler_type_t type) { if (type) return clang::QualType::getFromOpaquePtr(type); return clang::QualType(); } - + static clang::QualType - GetCanonicalQualType (lldb::opaque_compiler_type_t type) + GetCanonicalQualType(lldb::opaque_compiler_type_t type) { if (type) return clang::QualType::getFromOpaquePtr(type).getCanonicalType(); return clang::QualType(); } +protected: //------------------------------------------------------------------ // Classes that inherit from ClangASTContext can see and modify these //------------------------------------------------------------------ + // clang-format off std::string m_target_triple; std::unique_ptr<clang::ASTContext> m_ast_ap; std::unique_ptr<clang::LangOptions> m_language_options_ap; @@ -1215,7 +1206,8 @@ protected: std::unique_ptr<clang::IdentifierTable> m_identifier_table_ap; std::unique_ptr<clang::SelectorTable> m_selector_table_ap; std::unique_ptr<clang::Builtin::Context> m_builtins_ap; - std::unique_ptr<DWARFASTParser> m_dwarf_ast_parser_ap; + std::unique_ptr<DWARFASTParserClang> m_dwarf_ast_parser_ap; + std::unique_ptr<PDBASTParser> m_pdb_ast_parser_ap; std::unique_ptr<ClangASTSource> m_scratch_ast_source_ap; std::unique_ptr<clang::MangleContext> m_mangle_ctx_ap; CompleteTagDeclCallback m_callback_tag_decl; @@ -1224,8 +1216,7 @@ protected: uint32_t m_pointer_byte_size; bool m_ast_owned; bool m_can_evaluate_expressions; - std::map<void *, std::shared_ptr<void>> m_decl_objects; - + // clang-format on private: //------------------------------------------------------------------ // For ClangASTContext only diff --git a/include/lldb/Symbol/ClangASTImporter.h b/include/lldb/Symbol/ClangASTImporter.h index 8c3f8735c2e1..0ea7308d9541 100644 --- a/include/lldb/Symbol/ClangASTImporter.h +++ b/include/lldb/Symbol/ClangASTImporter.h @@ -19,6 +19,9 @@ // Other libraries and framework includes #include "clang/AST/ASTImporter.h" +#include "clang/AST/CharUnits.h" +#include "clang/AST/Decl.h" +#include "clang/AST/DeclCXX.h" #include "clang/Basic/FileManager.h" #include "clang/Basic/FileSystemOptions.h" @@ -26,6 +29,8 @@ #include "lldb/lldb-types.h" #include "lldb/Symbol/CompilerDeclContext.h" +#include "llvm/ADT/DenseMap.h" + namespace lldb_private { class ClangASTMetrics @@ -93,6 +98,16 @@ private: class ClangASTImporter { public: + struct LayoutInfo + { + LayoutInfo() : bit_size(0), alignment(0), field_offsets(), base_offsets(), vbase_offsets() {} + uint64_t bit_size; + uint64_t alignment; + llvm::DenseMap<const clang::FieldDecl *, uint64_t> field_offsets; + llvm::DenseMap<const clang::CXXRecordDecl *, clang::CharUnits> base_offsets; + llvm::DenseMap<const clang::CXXRecordDecl *, clang::CharUnits> vbase_offsets; + }; + ClangASTImporter () : m_file_manager(clang::FileSystemOptions()) { @@ -126,10 +141,28 @@ public: DeportDecl (clang::ASTContext *dst_ctx, clang::ASTContext *src_ctx, clang::Decl *decl); - + void - CompleteDecl (clang::Decl *decl); - + InsertRecordDecl(clang::RecordDecl *decl, const LayoutInfo &layout); + + bool + LayoutRecordType(const clang::RecordDecl *record_decl, uint64_t &bit_size, uint64_t &alignment, + llvm::DenseMap<const clang::FieldDecl *, uint64_t> &field_offsets, + llvm::DenseMap<const clang::CXXRecordDecl *, clang::CharUnits> &base_offsets, + llvm::DenseMap<const clang::CXXRecordDecl *, clang::CharUnits> &vbase_offsets); + + bool + CanImport(const CompilerType &type); + + bool + Import(const CompilerType &type); + + bool + CompleteType(const CompilerType &compiler_type); + + void + CompleteDecl(clang::Decl *decl); + bool CompleteTagDecl (clang::TagDecl *decl); @@ -381,6 +414,9 @@ private: GetDeclOrigin (const clang::Decl *decl); clang::FileManager m_file_manager; + typedef llvm::DenseMap<const clang::RecordDecl *, LayoutInfo> RecordDeclToLayoutMap; + + RecordDeclToLayoutMap m_record_decl_to_layout_map; }; } // namespace lldb_private diff --git a/include/lldb/Symbol/ClangUtil.h b/include/lldb/Symbol/ClangUtil.h new file mode 100644 index 000000000000..ee9ff5678d79 --- /dev/null +++ b/include/lldb/Symbol/ClangUtil.h @@ -0,0 +1,37 @@ +//===-- ClangUtil.h ---------------------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +// A collection of helper methods and data structures for manipulating clang +// types and decls. +//===----------------------------------------------------------------------===// + +#ifndef LLDB_SYMBOL_CLANGUTIL_H +#define LLDB_SYMBOL_CLANGUTIL_H + +#include "clang/AST/Type.h" + +#include "lldb/Symbol/CompilerType.h" + +namespace lldb_private +{ +struct ClangUtil +{ + static bool + IsClangType(const CompilerType &ct); + + static clang::QualType + GetQualType(const CompilerType &ct); + + static clang::QualType + GetCanonicalQualType(const CompilerType &ct); + + static CompilerType + RemoveFastQualifiers(const CompilerType &ct); +}; +} + +#endif diff --git a/include/lldb/Symbol/CompactUnwindInfo.h b/include/lldb/Symbol/CompactUnwindInfo.h index 239eb3ac77ad..6bf65a223471 100644 --- a/include/lldb/Symbol/CompactUnwindInfo.h +++ b/include/lldb/Symbol/CompactUnwindInfo.h @@ -10,11 +10,11 @@ #ifndef liblldb_CompactUnwindInfo_h_ #define liblldb_CompactUnwindInfo_h_ +#include <mutex> #include <vector> #include "lldb/Core/DataExtractor.h" #include "lldb/Core/RangeMap.h" -#include "lldb/Host/Mutex.h" #include "lldb/Symbol/ObjectFile.h" #include "lldb/Symbol/UnwindPlan.h" #include "lldb/lldb-private.h" @@ -133,11 +133,17 @@ private: bool CreateUnwindPlan_i386 (Target &target, FunctionInfo &function_info, UnwindPlan &unwind_plan, Address pc_or_function_start); + bool + CreateUnwindPlan_arm64 (Target &target, FunctionInfo &function_info, UnwindPlan &unwind_plan, Address pc_or_function_start); + + bool + CreateUnwindPlan_armv7 (Target &target, FunctionInfo &function_info, UnwindPlan &unwind_plan, Address pc_or_function_start); + ObjectFile &m_objfile; lldb::SectionSP m_section_sp; lldb::DataBufferSP m_section_contents_if_encrypted; // if the binary is encrypted, read the sect contents // out of live memory and cache them here - Mutex m_mutex; + std::mutex m_mutex; std::vector<UnwindIndex> m_indexes; LazyBool m_indexes_computed; // eLazyBoolYes once we've tried to parse the unwind info diff --git a/include/lldb/Symbol/CompileUnit.h b/include/lldb/Symbol/CompileUnit.h index 0c331c38f8c6..2f596f89ec5f 100644 --- a/include/lldb/Symbol/CompileUnit.h +++ b/include/lldb/Symbol/CompileUnit.h @@ -68,11 +68,16 @@ public: /// of this compile unit. /// /// @param[in] is_optimized - /// true if this compile unit was compiled with optimization. + /// A value that can initialized with eLazyBoolYes, eLazyBoolNo + /// or eLazyBoolCalculate. If set to eLazyBoolCalculate, then + /// an extra call into SymbolVendor will be made to calculate if + /// the compile unit is optimized will be made when + /// CompileUnit::GetIsOptimized() is called. /// /// @see lldb::LanguageType //------------------------------------------------------------------ - CompileUnit(const lldb::ModuleSP &module_sp, void *user_data, const char *pathname, lldb::user_id_t uid, lldb::LanguageType language, bool is_optimized); + CompileUnit(const lldb::ModuleSP &module_sp, void *user_data, const char *pathname, lldb::user_id_t uid, + lldb::LanguageType language, lldb_private::LazyBool is_optimized); //------------------------------------------------------------------ /// Construct with a module, file spec, UID and language. @@ -103,11 +108,16 @@ public: /// of this compile unit. /// /// @param[in] is_optimized - /// true if this compile unit was compiled with optimization. + /// A value that can initialized with eLazyBoolYes, eLazyBoolNo + /// or eLazyBoolCalculate. If set to eLazyBoolCalculate, then + /// an extra call into SymbolVendor will be made to calculate if + /// the compile unit is optimized will be made when + /// CompileUnit::GetIsOptimized() is called. /// /// @see lldb::LanguageType //------------------------------------------------------------------ - CompileUnit(const lldb::ModuleSP &module_sp, void *user_data, const FileSpec &file_spec, lldb::user_id_t uid, lldb::LanguageType language, bool is_optimized); + CompileUnit(const lldb::ModuleSP &module_sp, void *user_data, const FileSpec &file_spec, lldb::user_id_t uid, + lldb::LanguageType language, lldb_private::LazyBool is_optimized); //------------------------------------------------------------------ /// Destructor @@ -446,7 +456,7 @@ protected: std::unique_ptr<LineTable> m_line_table_ap; ///< Line table that will get parsed on demand. DebugMacrosSP m_debug_macros_sp; ///< Debug macros that will get parsed on demand. lldb::VariableListSP m_variables; ///< Global and static variable list that will get parsed on demand. - bool m_is_optimized; /// eLazyBoolYes if this compile unit was compiled with optimization. + lldb_private::LazyBool m_is_optimized; /// eLazyBoolYes if this compile unit was compiled with optimization. private: enum diff --git a/include/lldb/Symbol/CompilerDecl.h b/include/lldb/Symbol/CompilerDecl.h index b749e79b459a..19654ab165bb 100644 --- a/include/lldb/Symbol/CompilerDecl.h +++ b/include/lldb/Symbol/CompilerDecl.h @@ -65,12 +65,6 @@ public: IsClang () const; //---------------------------------------------------------------------- - // Object linked to the decl - //---------------------------------------------------------------------- - lldb::VariableSP - GetAsVariable (); - - //---------------------------------------------------------------------- // Accessors //---------------------------------------------------------------------- diff --git a/include/lldb/Symbol/CompilerDeclContext.h b/include/lldb/Symbol/CompilerDeclContext.h index 9135b44323b5..7432adac6133 100644 --- a/include/lldb/Symbol/CompilerDeclContext.h +++ b/include/lldb/Symbol/CompilerDeclContext.h @@ -66,7 +66,7 @@ public: IsClang () const; std::vector<CompilerDecl> - FindDeclByName (ConstString name); + FindDeclByName (ConstString name, const bool ignore_using_decls); //---------------------------------------------------------------------- /// Checks if this decl context represents a method of a class. diff --git a/include/lldb/Symbol/CompilerType.h b/include/lldb/Symbol/CompilerType.h index 4f3ecc54ba1a..36f6ef3ba6eb 100644 --- a/include/lldb/Symbol/CompilerType.h +++ b/include/lldb/Symbol/CompilerType.h @@ -149,9 +149,18 @@ public: IsFunctionPointerType () const; bool - IsIntegerType (bool &is_signed) const; + IsBlockPointerType (CompilerType *function_pointer_type_ptr) const; bool + IsIntegerType (bool &is_signed) const; + + bool + IsEnumerationType (bool &is_signed) const; + + bool + IsIntegerOrEnumerationType (bool &is_signed) const; + + bool IsPolymorphicClass () const; bool diff --git a/include/lldb/Symbol/DWARFCallFrameInfo.h b/include/lldb/Symbol/DWARFCallFrameInfo.h index cc497c039a4e..da7f87ced0a0 100644 --- a/include/lldb/Symbol/DWARFCallFrameInfo.h +++ b/include/lldb/Symbol/DWARFCallFrameInfo.h @@ -11,6 +11,7 @@ #define liblldb_DWARFCallFrameInfo_h_ #include <map> +#include <mutex> #include "lldb/Core/AddressRange.h" #include "lldb/Core/DataExtractor.h" @@ -18,7 +19,6 @@ #include "lldb/Core/RangeMap.h" #include "lldb/Core/VMRange.h" #include "lldb/Core/dwarf.h" -#include "lldb/Host/Mutex.h" #include "lldb/Symbol/ObjectFile.h" #include "lldb/Symbol/UnwindPlan.h" #include "lldb/lldb-private.h" @@ -73,6 +73,9 @@ public: void GetFunctionAddressAndSizeVector (FunctionAddressAndSizeVector &function_info); + void + ForEachFDEEntries(const std::function<bool(lldb::addr_t, uint32_t, dw_offset_t)>& callback); + private: enum { @@ -152,7 +155,7 @@ private: FDEEntryMap m_fde_index; bool m_fde_index_initialized; // only scan the section for FDEs once - Mutex m_fde_index_mutex; // and isolate the thread that does it + std::mutex m_fde_index_mutex; // and isolate the thread that does it bool m_is_eh_frame; diff --git a/include/lldb/Symbol/FuncUnwinders.h b/include/lldb/Symbol/FuncUnwinders.h index 728b4c6fcb32..6d5991cc2b33 100644 --- a/include/lldb/Symbol/FuncUnwinders.h +++ b/include/lldb/Symbol/FuncUnwinders.h @@ -1,12 +1,12 @@ #ifndef liblldb_FuncUnwinders_h #define liblldb_FuncUnwinders_h +#include <mutex> #include <vector> #include "lldb/Core/AddressRange.h" #include "lldb/Core/ArchSpec.h" #include "lldb/Core/AddressRange.h" -#include "lldb/Host/Mutex.h" namespace lldb_private { @@ -116,10 +116,18 @@ private: lldb::UnwindAssemblySP GetUnwindAssemblyProfiler (Target& target); + // Do a simplistic comparison for the register restore rule for getting + // the caller's pc value on two UnwindPlans -- returns LazyBoolYes if + // they have the same unwind rule for the pc, LazyBoolNo if they do not + // have the same unwind rule for the pc, and LazyBoolCalculate if it was + // unable to determine this for some reason. + lldb_private::LazyBool + CompareUnwindPlansForIdenticalInitialPCLocation (Thread& thread, const lldb::UnwindPlanSP &a, const lldb::UnwindPlanSP &b); + UnwindTable& m_unwind_table; AddressRange m_range; - Mutex m_mutex; + std::recursive_mutex m_mutex; lldb::UnwindPlanSP m_unwind_plan_assembly_sp; lldb::UnwindPlanSP m_unwind_plan_eh_frame_sp; diff --git a/include/lldb/Symbol/Function.h b/include/lldb/Symbol/Function.h index cd2df9b6078f..9892d620ce47 100644 --- a/include/lldb/Symbol/Function.h +++ b/include/lldb/Symbol/Function.h @@ -574,6 +574,14 @@ public: CompilerType GetCompilerType (); + //------------------------------------------------------------------ + /// Get the size of the prologue instructions for this function. The "prologue" + /// instructions include any instructions given line number 0 immediately following + /// the prologue end. + /// + /// @return + /// The size of the prologue. + //------------------------------------------------------------------ uint32_t GetPrologueByteSize (); diff --git a/include/lldb/Symbol/GoASTContext.h b/include/lldb/Symbol/GoASTContext.h index 09d79bacc585..ec0203bc3221 100644 --- a/include/lldb/Symbol/GoASTContext.h +++ b/include/lldb/Symbol/GoASTContext.h @@ -85,17 +85,6 @@ class GoASTContext : public TypeSystem return ConstString(); } - lldb::VariableSP - DeclGetVariable (void *opaque_decl) override - { - return lldb::VariableSP(); - } - - void - DeclLinkToObject (void *opaque_decl, std::shared_ptr<void> object) override - { - } - //---------------------------------------------------------------------- // CompilerDeclContext functions //---------------------------------------------------------------------- @@ -176,6 +165,8 @@ class GoASTContext : public TypeSystem CompilerType GetFunctionArgumentAtIndex(lldb::opaque_compiler_type_t type, const size_t index) override; bool IsFunctionPointerType(lldb::opaque_compiler_type_t type) override; + + bool IsBlockPointerType (lldb::opaque_compiler_type_t type, CompilerType *function_pointer_type_ptr) override; bool IsIntegerType(lldb::opaque_compiler_type_t type, bool &is_signed) override; diff --git a/include/lldb/Symbol/JavaASTContext.h b/include/lldb/Symbol/JavaASTContext.h new file mode 100644 index 000000000000..7d5a37649f6f --- /dev/null +++ b/include/lldb/Symbol/JavaASTContext.h @@ -0,0 +1,385 @@ +//===-- JavaASTContext.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_JavaASTContext_h_ +#define liblldb_JavaASTContext_h_ + +// C Includes +// C++ Includes +#include <map> +#include <memory> +#include <set> + +// Other libraries and framework includes +// Project includes +#include "lldb/Core/ConstString.h" +#include "lldb/Symbol/TypeSystem.h" + +namespace lldb_private +{ + +class JavaASTContext : public TypeSystem +{ +public: + class JavaType; + typedef std::map<ConstString, std::unique_ptr<JavaType>> JavaTypeMap; + + JavaASTContext(const ArchSpec &arch); + ~JavaASTContext() override; + + //------------------------------------------------------------------ + // PluginInterface functions + //------------------------------------------------------------------ + ConstString + GetPluginName() override; + + uint32_t + GetPluginVersion() override; + + static ConstString + GetPluginNameStatic(); + + static lldb::TypeSystemSP + CreateInstance(lldb::LanguageType language, Module *module, Target *target); + + static void + EnumerateSupportedLanguages(std::set<lldb::LanguageType> &languages_for_types, + std::set<lldb::LanguageType> &languages_for_expressions); + + static void + Initialize(); + + static void + Terminate(); + + DWARFASTParser * + GetDWARFParser() override; + + uint32_t + GetPointerByteSize() override; + + //---------------------------------------------------------------------- + // CompilerDecl functions + //---------------------------------------------------------------------- + ConstString + DeclGetName(void *opaque_decl) override; + + //---------------------------------------------------------------------- + // CompilerDeclContext functions + //---------------------------------------------------------------------- + + std::vector<CompilerDecl> + DeclContextFindDeclByName(void *opaque_decl_ctx, ConstString name, const bool ignore_imported_decls) override; + + bool + DeclContextIsStructUnionOrClass(void *opaque_decl_ctx) override; + + ConstString + DeclContextGetName(void *opaque_decl_ctx) override; + + bool + DeclContextIsClassMethod(void *opaque_decl_ctx, lldb::LanguageType *language_ptr, bool *is_instance_method_ptr, + ConstString *language_object_name_ptr) override; + + //---------------------------------------------------------------------- + // Tests + //---------------------------------------------------------------------- + + bool + IsArrayType(lldb::opaque_compiler_type_t type, CompilerType *element_type, uint64_t *size, + bool *is_incomplete) override; + + bool + IsAggregateType(lldb::opaque_compiler_type_t type) override; + + bool + IsCharType(lldb::opaque_compiler_type_t type) override; + + bool + IsFloatingPointType(lldb::opaque_compiler_type_t type, uint32_t &count, bool &is_complex) override; + + bool + IsFunctionType(lldb::opaque_compiler_type_t type, bool *is_variadic_ptr = nullptr) override; + + size_t + GetNumberOfFunctionArguments(lldb::opaque_compiler_type_t type) override; + + CompilerType + GetFunctionArgumentAtIndex(lldb::opaque_compiler_type_t type, const size_t index) override; + + bool + IsFunctionPointerType(lldb::opaque_compiler_type_t type) override; + + bool + IsBlockPointerType (lldb::opaque_compiler_type_t type, CompilerType *function_pointer_type_ptr) override; + + bool + IsIntegerType(lldb::opaque_compiler_type_t type, bool &is_signed) override; + + bool + IsPossibleDynamicType(lldb::opaque_compiler_type_t type, CompilerType *target_type, bool check_cplusplus, + bool check_objc) override; + + bool + IsPointerType(lldb::opaque_compiler_type_t type, CompilerType *pointee_type = nullptr) override; + + bool + IsReferenceType(lldb::opaque_compiler_type_t type, CompilerType *pointee_type = nullptr, + bool *is_rvalue = nullptr) override; + + bool + IsPointerOrReferenceType(lldb::opaque_compiler_type_t type, CompilerType *pointee_type = nullptr) override; + + bool + IsScalarType(lldb::opaque_compiler_type_t type) override; + + bool + IsVoidType(lldb::opaque_compiler_type_t type) override; + + bool + IsCStringType(lldb::opaque_compiler_type_t type, uint32_t &length) override; + + bool + IsRuntimeGeneratedType(lldb::opaque_compiler_type_t type) override; + + bool + IsTypedefType(lldb::opaque_compiler_type_t type) override; + + bool + IsVectorType(lldb::opaque_compiler_type_t type, CompilerType *element_type, uint64_t *size) override; + + bool + IsPolymorphicClass(lldb::opaque_compiler_type_t type) override; + + bool + IsCompleteType(lldb::opaque_compiler_type_t type) override; + + bool + IsConst(lldb::opaque_compiler_type_t type) override; + + bool + IsBeingDefined(lldb::opaque_compiler_type_t type) override; + + bool + IsDefined(lldb::opaque_compiler_type_t type) override; + + uint32_t + IsHomogeneousAggregate(lldb::opaque_compiler_type_t type, CompilerType *base_type_ptr) override; + + bool + SupportsLanguage(lldb::LanguageType language) override; + + bool + GetCompleteType(lldb::opaque_compiler_type_t type) override; + + ConstString + GetTypeName(lldb::opaque_compiler_type_t type) override; + + uint32_t + GetTypeInfo(lldb::opaque_compiler_type_t type, CompilerType *pointee_or_element_compiler_type = nullptr) override; + + lldb::TypeClass + GetTypeClass(lldb::opaque_compiler_type_t type) override; + + lldb::LanguageType + GetMinimumLanguage(lldb::opaque_compiler_type_t type) override; + + CompilerType + GetArrayElementType(lldb::opaque_compiler_type_t type, uint64_t *stride = nullptr) override; + + CompilerType + GetPointeeType(lldb::opaque_compiler_type_t type) override; + + CompilerType + GetPointerType(lldb::opaque_compiler_type_t type) override; + + CompilerType + GetCanonicalType(lldb::opaque_compiler_type_t type) override; + + CompilerType + GetFullyUnqualifiedType(lldb::opaque_compiler_type_t type) override; + + CompilerType + GetNonReferenceType(lldb::opaque_compiler_type_t type) override; + + CompilerType + GetTypedefedType(lldb::opaque_compiler_type_t type) override; + + CompilerType + GetBasicTypeFromAST(lldb::BasicType basic_type) override; + + CompilerType + GetBuiltinTypeForEncodingAndBitSize(lldb::Encoding encoding, size_t bit_size) override; + + size_t + GetTypeBitAlign(lldb::opaque_compiler_type_t type) override; + + lldb::BasicType + GetBasicTypeEnumeration(lldb::opaque_compiler_type_t type) override; + + uint64_t + GetBitSize(lldb::opaque_compiler_type_t type, ExecutionContextScope *exe_scope) override; + + lldb::Encoding + GetEncoding(lldb::opaque_compiler_type_t type, uint64_t &count) override; + + lldb::Format + GetFormat(lldb::opaque_compiler_type_t type) override; + + unsigned + GetTypeQualifiers(lldb::opaque_compiler_type_t type) override; + + size_t + GetNumTemplateArguments(lldb::opaque_compiler_type_t type) override; + + CompilerType + GetTemplateArgument(lldb::opaque_compiler_type_t type, size_t idx, lldb::TemplateArgumentKind &kind) override; + + int + GetFunctionArgumentCount(lldb::opaque_compiler_type_t type) override; + + CompilerType + GetFunctionArgumentTypeAtIndex(lldb::opaque_compiler_type_t type, size_t idx) override; + + CompilerType + GetFunctionReturnType(lldb::opaque_compiler_type_t type) override; + + size_t + GetNumMemberFunctions(lldb::opaque_compiler_type_t type) override; + + TypeMemberFunctionImpl + GetMemberFunctionAtIndex(lldb::opaque_compiler_type_t type, size_t idx) override; + + uint32_t + GetNumFields(lldb::opaque_compiler_type_t type) override; + + CompilerType + GetFieldAtIndex(lldb::opaque_compiler_type_t type, size_t idx, std::string &name, uint64_t *bit_offset_ptr, + uint32_t *bitfield_bit_size_ptr, bool *is_bitfield_ptr) override; + + uint32_t + GetNumChildren(lldb::opaque_compiler_type_t type, bool omit_empty_base_classes) override; + + uint32_t + GetNumDirectBaseClasses(lldb::opaque_compiler_type_t type) override; + + uint32_t + GetNumVirtualBaseClasses(lldb::opaque_compiler_type_t type) override; + + CompilerType + GetDirectBaseClassAtIndex(lldb::opaque_compiler_type_t type, size_t idx, uint32_t *bit_offset_ptr) override; + + CompilerType + GetVirtualBaseClassAtIndex(lldb::opaque_compiler_type_t type, size_t idx, uint32_t *bit_offset_ptr) override; + + size_t + ConvertStringToFloatValue(lldb::opaque_compiler_type_t type, const char *s, uint8_t *dst, size_t dst_size) override; + + void + DumpValue(lldb::opaque_compiler_type_t type, ExecutionContext *exe_ctx, Stream *s, lldb::Format format, + const DataExtractor &data, lldb::offset_t data_offset, size_t data_byte_size, uint32_t bitfield_bit_size, + uint32_t bitfield_bit_offset, bool show_types, bool show_summary, bool verbose, uint32_t depth) override; + + bool + DumpTypeValue(lldb::opaque_compiler_type_t type, Stream *s, lldb::Format format, const DataExtractor &data, + lldb::offset_t data_offset, size_t data_byte_size, uint32_t bitfield_bit_size, + uint32_t bitfield_bit_offset, ExecutionContextScope *exe_scope) override; + + void + DumpTypeDescription(lldb::opaque_compiler_type_t type) override; + + void + DumpTypeDescription(lldb::opaque_compiler_type_t type, Stream *s) override; + + void + DumpSummary(lldb::opaque_compiler_type_t type, ExecutionContext *exe_ctx, Stream *s, const DataExtractor &data, + lldb::offset_t data_offset, size_t data_byte_size) override; + + CompilerType + GetChildCompilerTypeAtIndex(lldb::opaque_compiler_type_t type, ExecutionContext *exe_ctx, size_t idx, + bool transparent_pointers, bool omit_empty_base_classes, bool ignore_array_bounds, + std::string &child_name, uint32_t &child_byte_size, int32_t &child_byte_offset, + uint32_t &child_bitfield_bit_size, uint32_t &child_bitfield_bit_offset, + bool &child_is_base_class, bool &child_is_deref_of_parent, ValueObject *valobj, + uint64_t &language_flags) override; + + uint32_t + GetIndexOfChildWithName(lldb::opaque_compiler_type_t type, const char *name, bool omit_empty_base_classes) override; + + size_t + GetIndexOfChildMemberWithName(lldb::opaque_compiler_type_t type, const char *name, bool omit_empty_base_classes, + std::vector<uint32_t> &child_indexes) override; + + CompilerType + GetLValueReferenceType(lldb::opaque_compiler_type_t type) override; + + ConstString + DeclContextGetScopeQualifiedName(lldb::opaque_compiler_type_t opaque_decl_ctx) override; + + CompilerType + CreateBaseType(const ConstString &name); + + CompilerType + CreateObjectType(const ConstString &name, const ConstString &linkage_name, uint32_t byte_size); + + CompilerType + CreateArrayType(const ConstString &linkage_name, const CompilerType &element_type, + const DWARFExpression &length_expression, const lldb::addr_t data_offset); + + CompilerType + CreateReferenceType(const CompilerType &pointee_type); + + void + CompleteObjectType(const CompilerType &object_type); + + void + AddBaseClassToObject(const CompilerType &object_type, const CompilerType &member_type, uint32_t member_offset); + + void + AddMemberToObject(const CompilerType &object_type, const ConstString &name, const CompilerType &member_type, + uint32_t member_offset); + + void + SetDynamicTypeId(const CompilerType &type, const DWARFExpression &type_id); + + static uint64_t + CalculateDynamicTypeId(ExecutionContext *exe_ctx, const CompilerType &type, ValueObject &in_value); + + static ConstString + GetLinkageName(const CompilerType &type); + + static uint32_t + CalculateArraySize(const CompilerType &type, ValueObject &in_value); + + static uint64_t + CalculateArrayElementOffset(const CompilerType &type, size_t index); + + //------------------------------------------------------------------ + // llvm casting support + //------------------------------------------------------------------ + static bool + classof(const TypeSystem *ts) + { + return ts->getKind() == TypeSystem::eKindJava; + } + +private: + uint32_t m_pointer_byte_size; + std::unique_ptr<DWARFASTParser> m_dwarf_ast_parser_ap; + JavaTypeMap m_array_type_map; + JavaTypeMap m_base_type_map; + JavaTypeMap m_reference_type_map; + JavaTypeMap m_object_type_map; + + JavaASTContext(const JavaASTContext &) = delete; + const JavaASTContext & + operator=(const JavaASTContext &) = delete; +}; +} +#endif // liblldb_JavaASTContext_h_ diff --git a/include/lldb/Symbol/LineEntry.h b/include/lldb/Symbol/LineEntry.h index 374c04a7fcec..e6a05c10a764 100644 --- a/include/lldb/Symbol/LineEntry.h +++ b/include/lldb/Symbol/LineEntry.h @@ -168,10 +168,21 @@ struct LineEntry GetSameLineContiguousAddressRange () const; //------------------------------------------------------------------ + /// Apply file mappings from target.source-map to the LineEntry's file. + /// + /// @param[in] target_sp + /// Shared pointer to the target this LineEntry belongs to. + //------------------------------------------------------------------ + + void + ApplyFileMappings(lldb::TargetSP target_sp); + + //------------------------------------------------------------------ // Member variables. //------------------------------------------------------------------ AddressRange range; ///< The section offset address range for this line entry. - FileSpec file; + FileSpec file; ///< The source file, possibly mapped by the target.source-map setting + FileSpec original_file; ///< The original source file, from debug info. uint32_t line; ///< The source line number, or zero if there is no line number information. uint16_t column; ///< The column number of the source line, or zero if there is no column information. uint16_t is_start_of_statement:1, ///< Indicates this entry is the beginning of a statement. diff --git a/include/lldb/Symbol/ObjectFile.h b/include/lldb/Symbol/ObjectFile.h index 4b0a2f9ff936..53f0f3c80517 100644 --- a/include/lldb/Symbol/ObjectFile.h +++ b/include/lldb/Symbol/ObjectFile.h @@ -551,6 +551,35 @@ public: GetUnwindTable () { return m_unwind_table; } //------------------------------------------------------------------ + /// Returns if the function bounds for symbols in this symbol file + /// are likely accurate. + /// + /// The unwinder can emulate the instructions of functions to understand + /// prologue/epilogue code sequences, where registers are spilled on + /// the stack, etc. This feature relies on having the correct start + /// addresses of all functions. If the ObjectFile has a way to tell + /// that symbols have been stripped and there's no way to reconstruct + /// start addresses (e.g. LC_FUNCTION_STARTS on Mach-O, or eh_frame + /// unwind info), the ObjectFile should indicate that assembly emulation + /// should not be used for this module. + /// + /// It is uncommon for this to return false. An ObjectFile needs to + /// be sure that symbol start addresses are unavailable before false + /// is returned. If it is unclear, this should return true. + /// + /// @return + /// Returns true if assembly emulation should be used for this + /// module. + /// Only returns false if the ObjectFile is sure that symbol + /// addresses are insufficient for accurate assembly emulation. + //------------------------------------------------------------------ + virtual bool + AllowAssemblyEmulationUnwindPlans () + { + return true; + } + + //------------------------------------------------------------------ /// Similar to Process::GetImageInfoAddress(). /// /// Some platforms embed auxiliary structures useful to debuggers in the @@ -860,6 +889,7 @@ protected: const lldb::addr_t m_memory_addr; std::unique_ptr<lldb_private::SectionList> m_sections_ap; std::unique_ptr<lldb_private::Symtab> m_symtab_ap; + uint32_t m_synthetic_symbol_idx; //------------------------------------------------------------------ /// Sets the architecture for a module. At present the architecture @@ -873,7 +903,11 @@ protected: /// Returns \b true if the architecture was changed, \b /// false otherwise. //------------------------------------------------------------------ - bool SetModulesArchitecture (const ArchSpec &new_arch); + bool + SetModulesArchitecture (const ArchSpec &new_arch); + + ConstString + GetNextSyntheticSymbolName(); private: DISALLOW_COPY_AND_ASSIGN (ObjectFile); diff --git a/include/lldb/Symbol/Symbol.h b/include/lldb/Symbol/Symbol.h index c77d3dea4bd2..43f29f368d92 100644 --- a/include/lldb/Symbol/Symbol.h +++ b/include/lldb/Symbol/Symbol.h @@ -383,6 +383,9 @@ public: bool prefer_file_cache, Stream &strm); + bool + ContainsFileAddress (lldb::addr_t file_addr) const; + protected: // This is the internal guts of ResolveReExportedSymbol, it assumes reexport_name is not null, and that module_spec // is valid. We track the modules we've already seen to make sure we don't get caught in a cycle. diff --git a/include/lldb/Symbol/SymbolContext.h b/include/lldb/Symbol/SymbolContext.h index 9cb709d24011..f0e8e3590a8a 100644 --- a/include/lldb/Symbol/SymbolContext.h +++ b/include/lldb/Symbol/SymbolContext.h @@ -244,6 +244,9 @@ public: uint32_t range_idx, bool use_inline_block_range, AddressRange &range) const; + + bool + GetAddressRangeFromHereToEndLine(uint32_t end_line, AddressRange &range, Error &error); void GetDescription(Stream *s, diff --git a/include/lldb/Symbol/SymbolFile.h b/include/lldb/Symbol/SymbolFile.h index fe74ad4f933e..db97ab4f9b65 100644 --- a/include/lldb/Symbol/SymbolFile.h +++ b/include/lldb/Symbol/SymbolFile.h @@ -17,6 +17,8 @@ #include "lldb/Symbol/CompilerDeclContext.h" #include "lldb/Symbol/Type.h" +#include "llvm/ADT/DenseSet.h" + namespace lldb_private { class SymbolFile : @@ -125,6 +127,11 @@ public: virtual bool ParseCompileUnitLineTable (const SymbolContext& sc) = 0; virtual bool ParseCompileUnitDebugMacros (const SymbolContext& sc) = 0; virtual bool ParseCompileUnitSupportFiles (const SymbolContext& sc, FileSpecList& support_files) = 0; + virtual bool + ParseCompileUnitIsOptimized(const lldb_private::SymbolContext &sc) + { + return false; + } virtual bool ParseImportedModules (const SymbolContext &sc, std::vector<ConstString> &imported_modules) = 0; virtual size_t ParseFunctionBlocks (const SymbolContext& sc) = 0; virtual size_t ParseTypes (const SymbolContext& sc) = 0; @@ -141,7 +148,7 @@ public: virtual uint32_t FindGlobalVariables (const RegularExpression& regex, bool append, uint32_t max_matches, VariableList& variables); virtual uint32_t FindFunctions (const ConstString &name, const CompilerDeclContext *parent_decl_ctx, uint32_t name_type_mask, bool include_inlines, bool append, SymbolContextList& sc_list); virtual uint32_t FindFunctions (const RegularExpression& regex, bool include_inlines, bool append, SymbolContextList& sc_list); - virtual uint32_t FindTypes (const SymbolContext& sc, const ConstString &name, const CompilerDeclContext *parent_decl_ctx, bool append, uint32_t max_matches, TypeMap& types); + virtual uint32_t FindTypes (const SymbolContext& sc, const ConstString &name, const CompilerDeclContext *parent_decl_ctx, bool append, uint32_t max_matches, llvm::DenseSet<lldb_private::SymbolFile *> &searched_symbol_files, TypeMap& types); virtual size_t FindTypes (const std::vector<CompilerContext> &context, bool append, TypeMap& types); virtual void GetMangledNamesForFunction(const std::string &scope_qualified_name, std::vector<ConstString> &mangled_names); diff --git a/include/lldb/Symbol/SymbolVendor.h b/include/lldb/Symbol/SymbolVendor.h index 19461718ed13..e992c5cde607 100644 --- a/include/lldb/Symbol/SymbolVendor.h +++ b/include/lldb/Symbol/SymbolVendor.h @@ -17,6 +17,7 @@ #include "lldb/Core/PluginInterface.h" #include "lldb/Symbol/TypeList.h" #include "lldb/Symbol/TypeMap.h" +#include "llvm/ADT/DenseSet.h" namespace lldb_private { @@ -67,7 +68,10 @@ public: virtual bool ParseCompileUnitSupportFiles (const SymbolContext& sc, FileSpecList& support_files); - + + virtual bool + ParseCompileUnitIsOptimized(const SymbolContext &sc); + virtual bool ParseImportedModules (const SymbolContext &sc, std::vector<ConstString> &imported_modules); @@ -129,6 +133,7 @@ public: const CompilerDeclContext *parent_decl_ctx, bool append, size_t max_matches, + llvm::DenseSet<lldb_private::SymbolFile *> &searched_symbol_files, TypeMap& types); virtual size_t diff --git a/include/lldb/Symbol/Symtab.h b/include/lldb/Symbol/Symtab.h index 130f02c0e68b..4203a3f7599a 100644 --- a/include/lldb/Symbol/Symtab.h +++ b/include/lldb/Symbol/Symtab.h @@ -11,12 +11,12 @@ #ifndef liblldb_Symtab_h_ #define liblldb_Symtab_h_ +#include <mutex> #include <vector> #include "lldb/lldb-private.h" #include "lldb/Core/RangeMap.h" #include "lldb/Core/UniqueCStringMap.h" -#include "lldb/Host/Mutex.h" #include "lldb/Symbol/Symbol.h" namespace lldb_private { @@ -50,10 +50,11 @@ public: void Dump(Stream *s, Target *target, SortOrder sort_type); void Dump(Stream *s, Target *target, std::vector<uint32_t>& indexes) const; uint32_t GetIndexForSymbol (const Symbol *symbol) const; - Mutex & GetMutex () - { - return m_mutex; - } + std::recursive_mutex & + GetMutex() + { + return m_mutex; + } Symbol * FindSymbolByID (lldb::user_id_t uid) const; Symbol * SymbolAtIndex (size_t idx); const Symbol * SymbolAtIndex (size_t idx) const; @@ -79,7 +80,7 @@ public: size_t FindAllSymbolsWithNameAndType (const ConstString &name, lldb::SymbolType symbol_type, Debug symbol_debug_type, Visibility symbol_visibility, std::vector<uint32_t>& symbol_indexes); size_t FindAllSymbolsMatchingRexExAndType (const RegularExpression ®ex, lldb::SymbolType symbol_type, Debug symbol_debug_type, Visibility symbol_visibility, std::vector<uint32_t>& symbol_indexes); Symbol * FindFirstSymbolWithNameAndType (const ConstString &name, lldb::SymbolType symbol_type, Debug symbol_debug_type, Visibility symbol_visibility); - Symbol * FindSymbolContainingFileAddress (lldb::addr_t file_addr, const uint32_t* indexes, uint32_t num_indexes); + Symbol * FindSymbolAtFileAddress (lldb::addr_t file_addr); Symbol * FindSymbolContainingFileAddress (lldb::addr_t file_addr); void ForEachSymbolContainingFileAddress(lldb::addr_t file_addr, std::function<bool(Symbol *)> const &callback); size_t FindFunctionSymbols (const ConstString &name, uint32_t name_type_mask, SymbolContextList& sc_list); @@ -124,7 +125,7 @@ protected: UniqueCStringMap<uint32_t> m_basename_to_index; UniqueCStringMap<uint32_t> m_method_to_index; UniqueCStringMap<uint32_t> m_selector_to_index; - mutable Mutex m_mutex; // Provide thread safety for this symbol table + mutable std::recursive_mutex m_mutex; // Provide thread safety for this symbol table bool m_file_addr_to_index_computed:1, m_name_indexes_computed:1; private: diff --git a/include/lldb/Symbol/Type.h b/include/lldb/Symbol/Type.h index 224e0a112df3..9158f28998e3 100644 --- a/include/lldb/Symbol/Type.h +++ b/include/lldb/Symbol/Type.h @@ -428,7 +428,10 @@ public: SetType (lldb::TypeSP type) { type_sp = type; - compiler_type = type_sp->GetForwardCompilerType (); + if (type_sp) + compiler_type = type_sp->GetForwardCompilerType (); + else + compiler_type.Clear(); } lldb::TypeSP @@ -955,13 +958,13 @@ public: uint64_t GetValueAsUnsigned () const { - return *m_value.getRawData(); + return m_value.getZExtValue(); } int64_t GetValueAsSigned () const { - return (int64_t) *m_value.getRawData(); + return m_value.getSExtValue(); } protected: diff --git a/include/lldb/Symbol/TypeSystem.h b/include/lldb/Symbol/TypeSystem.h index 9b43b9dec37b..466699366f0a 100644 --- a/include/lldb/Symbol/TypeSystem.h +++ b/include/lldb/Symbol/TypeSystem.h @@ -14,6 +14,7 @@ // C++ Includes #include <functional> #include <map> +#include <mutex> #include <string> // Other libraries and framework includes @@ -24,7 +25,6 @@ #include "lldb/lldb-private.h" #include "lldb/Core/PluginInterface.h" #include "lldb/Expression/Expression.h" -#include "lldb/Host/Mutex.h" #include "lldb/Symbol/CompilerDecl.h" #include "lldb/Symbol/CompilerDeclContext.h" @@ -74,6 +74,7 @@ public: eKindClang, eKindSwift, eKindGo, + eKindJava, kNumKinds }; @@ -92,8 +93,14 @@ public: static lldb::TypeSystemSP CreateInstance (lldb::LanguageType language, Target *target); + + // Free up any resources associated with this TypeSystem. Done before removing + // all the TypeSystems from the TypeSystemMap. + virtual void + Finalize() {} + virtual DWARFASTParser * - GetDWARFParser () + GetDWARFParser() { return nullptr; } @@ -120,12 +127,6 @@ public: virtual ConstString DeclGetMangledName (void *opaque_decl); - virtual lldb::VariableSP - DeclGetVariable (void *opaque_decl) = 0; - - virtual void - DeclLinkToObject (void *opaque_decl, std::shared_ptr<void> object) = 0; - virtual CompilerDeclContext DeclGetDeclContext (void *opaque_decl); @@ -143,7 +144,9 @@ public: //---------------------------------------------------------------------- virtual std::vector<CompilerDecl> - DeclContextFindDeclByName (void *opaque_decl_ctx, ConstString name); + DeclContextFindDeclByName (void *opaque_decl_ctx, + ConstString name, + const bool ignore_imported_decls); virtual bool DeclContextIsStructUnionOrClass (void *opaque_decl_ctx) = 0; @@ -201,9 +204,19 @@ public: IsFunctionPointerType (lldb::opaque_compiler_type_t type) = 0; virtual bool - IsIntegerType (lldb::opaque_compiler_type_t type, bool &is_signed) = 0; + IsBlockPointerType (lldb::opaque_compiler_type_t type, CompilerType *function_pointer_type_ptr) = 0; virtual bool + IsIntegerType (lldb::opaque_compiler_type_t type, bool &is_signed) = 0; + + virtual bool + IsEnumerationType (lldb::opaque_compiler_type_t type, bool &is_signed) + { + is_signed = false; + return false; + } + + virtual bool IsPossibleDynamicType (lldb::opaque_compiler_type_t type, CompilerType *target_type, // Can pass NULL bool check_cplusplus, @@ -582,6 +595,8 @@ protected: TypeSystemMap (); ~TypeSystemMap(); + // Clear calls Finalize on all the TypeSystems managed by this map, and then + // empties the map. void Clear (); @@ -597,9 +612,15 @@ protected: GetTypeSystemForLanguage (lldb::LanguageType language, Target *target, bool can_create); protected: + // This function does not take the map mutex, and should only be called from + // functions that do take the mutex. + void + AddToMap (lldb::LanguageType language, lldb::TypeSystemSP const &type_system_sp); + typedef std::map<lldb::LanguageType, lldb::TypeSystemSP> collection; - mutable Mutex m_mutex; ///< A mutex to keep this object happy in multi-threaded environments. + mutable std::mutex m_mutex; ///< A mutex to keep this object happy in multi-threaded environments. collection m_map; + bool m_clear_in_progress; }; } // namespace lldb_private diff --git a/include/lldb/Symbol/UnwindPlan.h b/include/lldb/Symbol/UnwindPlan.h index 71100138413d..64c00bf12c27 100644 --- a/include/lldb/Symbol/UnwindPlan.h +++ b/include/lldb/Symbol/UnwindPlan.h @@ -116,6 +116,12 @@ public: return m_type == unspecified; } + bool + IsUndefined () const + { + return m_type == undefined; + } + bool IsCFAPlusOffset () const { @@ -539,7 +545,7 @@ public: AppendRow (const RowSP& row_sp); void - InsertRow (const RowSP& row_sp); + InsertRow (const RowSP& row_sp, bool replace_existing = false); // Returns a pointer to the best row for the given offset into the function's instructions. // If offset is -1 it indicates that the function start is unknown - the final row in the UnwindPlan is returned. diff --git a/include/lldb/Symbol/UnwindTable.h b/include/lldb/Symbol/UnwindTable.h index f69e4660de24..cb0080aff881 100644 --- a/include/lldb/Symbol/UnwindTable.h +++ b/include/lldb/Symbol/UnwindTable.h @@ -12,9 +12,9 @@ #define liblldb_UnwindTable_h #include <map> +#include <mutex> #include "lldb/lldb-private.h" -#include "lldb/Host/Mutex.h" namespace lldb_private { @@ -40,6 +40,9 @@ public: lldb::FuncUnwindersSP GetFuncUnwindersContainingAddress (const Address& addr, SymbolContext &sc); + bool + GetAllowAssemblyEmulationUnwindPlans (); + // Normally when we create a new FuncUnwinders object we track it in this UnwindTable so it can // be reused later. But for the target modules show-unwind we want to create brand new // UnwindPlans for the function of interest - so ignore any existing FuncUnwinders for that @@ -66,7 +69,7 @@ private: collection m_unwinds; bool m_initialized; // delay some initialization until ObjectFile is set up - Mutex m_mutex; + std::mutex m_mutex; std::unique_ptr<DWARFCallFrameInfo> m_eh_frame_up; std::unique_ptr<CompactUnwindInfo> m_compact_unwind_up; diff --git a/include/lldb/Symbol/Variable.h b/include/lldb/Symbol/Variable.h index 1cac5d0c5649..00761424d107 100644 --- a/include/lldb/Symbol/Variable.h +++ b/include/lldb/Symbol/Variable.h @@ -17,6 +17,7 @@ #include "lldb/lldb-private.h" #include "lldb/lldb-enumerations.h" #include "lldb/Core/Mangled.h" +#include "lldb/Core/RangeMap.h" #include "lldb/Core/UserID.h" #include "lldb/Expression/DWARFExpression.h" #include "lldb/Symbol/Declaration.h" @@ -27,6 +28,8 @@ class Variable : public UserID, public std::enable_shared_from_this<Variable> { public: + typedef RangeVector<lldb::addr_t, lldb::addr_t> RangeList; + //------------------------------------------------------------------ // Constructors and Destructors //------------------------------------------------------------------ @@ -36,6 +39,7 @@ public: const lldb::SymbolFileTypeSP &symfile_type_sp, lldb::ValueType scope, SymbolContextScope *owner_scope, + const RangeList& scope_range, Declaration* decl, const DWARFExpression& location, bool external, @@ -178,12 +182,14 @@ public: CompilerDecl GetDecl (); + protected: ConstString m_name; // The basename of the variable (no namespaces) Mangled m_mangled; // The mangled name of the variable lldb::SymbolFileTypeSP m_symfile_type_sp; // The type pointer of the variable (int, struct, class, etc) lldb::ValueType m_scope; // global, parameter, local SymbolContextScope *m_owner_scope; // The symbol file scope that this variable was defined in + RangeList m_scope_range; // The list of ranges inside the owner's scope where this variable is valid Declaration m_declaration; // Declaration location for this item. DWARFExpression m_location; // The location of this variable that can be fed to DWARFExpression::Evaluate() uint8_t m_external:1, // Visible outside the containing compile unit? diff --git a/include/lldb/Target/ABI.h b/include/lldb/Target/ABI.h index 94826d173500..cd0b57e61ff8 100644 --- a/include/lldb/Target/ABI.h +++ b/include/lldb/Target/ABI.h @@ -16,6 +16,7 @@ // Project includes #include "lldb/Core/Error.h" #include "lldb/Core/PluginInterface.h" +#include "lldb/Symbol/UnwindPlan.h" #include "lldb/lldb-private.h" #include "llvm/ADT/ArrayRef.h" @@ -110,6 +111,10 @@ public: virtual bool RegisterIsVolatile (const RegisterInfo *reg_info) = 0; + virtual bool + GetFallbackRegisterLocation (const RegisterInfo *reg_info, + UnwindPlan::Row::RegisterLocation &unwind_regloc); + // Should take a look at a call frame address (CFA) which is just the stack // pointer value upon entry to a function. ABIs usually impose alignment // restrictions (4, 8 or 16 byte aligned), and zero is usually not allowed. diff --git a/include/lldb/Target/DynamicLoader.h b/include/lldb/Target/DynamicLoader.h index 5eada0342a21..2c4956829b29 100644 --- a/include/lldb/Target/DynamicLoader.h +++ b/include/lldb/Target/DynamicLoader.h @@ -71,7 +71,7 @@ public: /// The destructor is virtual since this class is designed to be /// inherited from by the plug-in instance. //------------------------------------------------------------------ - ~DynamicLoader() override; + virtual ~DynamicLoader() override; //------------------------------------------------------------------ /// Called after attaching a process. @@ -238,11 +238,19 @@ public: /// LLDB_INVALID_ADDRESS is returned. //------------------------------------------------------------------ virtual lldb::addr_t - GetThreadLocalData (const lldb::ModuleSP module, const lldb::ThreadSP thread) + GetThreadLocalData(const lldb::ModuleSP module, const lldb::ThreadSP thread, lldb::addr_t tls_file_addr) { return LLDB_INVALID_ADDRESS; } + /// Locates or creates a module given by @p file and updates/loads the + /// resulting module at the virtual base address @p base_addr. + virtual lldb::ModuleSP + LoadModuleAtAddress(const lldb_private::FileSpec &file, + lldb::addr_t link_map_addr, + lldb::addr_t base_addr, + bool base_addr_is_offset); + protected: //------------------------------------------------------------------ // Utility methods for derived classes @@ -282,14 +290,6 @@ protected: void UnloadSectionsCommon(const lldb::ModuleSP module); - /// Locates or creates a module given by @p file and updates/loads the - /// resulting module at the virtual base address @p base_addr. - virtual lldb::ModuleSP - LoadModuleAtAddress(const lldb_private::FileSpec &file, - lldb::addr_t link_map_addr, - lldb::addr_t base_addr, - bool base_addr_is_offset); - const lldb_private::SectionList * GetSectionListFromModule(const lldb::ModuleSP module) const; diff --git a/include/lldb/Target/ExecutionContext.h b/include/lldb/Target/ExecutionContext.h index cdf55e3b744c..da585e4c9dad 100644 --- a/include/lldb/Target/ExecutionContext.h +++ b/include/lldb/Target/ExecutionContext.h @@ -12,11 +12,12 @@ // C Includes // C++ Includes +#include <mutex> + // Other libraries and framework includes // Project includes #include "lldb/lldb-private.h" #include "lldb/Target/StackID.h" -#include "lldb/Host/Mutex.h" namespace lldb_private { @@ -412,8 +413,8 @@ public: // These two variants take in a locker, and grab the target, lock the API mutex into locker, then // fill in the rest of the shared pointers. - ExecutionContext (const ExecutionContextRef &exe_ctx_ref, Mutex::Locker &locker); - ExecutionContext (const ExecutionContextRef *exe_ctx_ref, Mutex::Locker &locker); + ExecutionContext(const ExecutionContextRef &exe_ctx_ref, std::unique_lock<std::recursive_mutex> &locker); + ExecutionContext(const ExecutionContextRef *exe_ctx_ref, std::unique_lock<std::recursive_mutex> &locker); //------------------------------------------------------------------ // Create execution contexts from execution context scopes //------------------------------------------------------------------ diff --git a/include/lldb/Target/InstrumentationRuntime.h b/include/lldb/Target/InstrumentationRuntime.h index 70aa62908406..a5dc853ab55b 100644 --- a/include/lldb/Target/InstrumentationRuntime.h +++ b/include/lldb/Target/InstrumentationRuntime.h @@ -20,6 +20,7 @@ #include "lldb/lldb-private.h" #include "lldb/lldb-types.h" #include "lldb/Core/PluginInterface.h" +#include "lldb/Core/StructuredData.h" namespace lldb_private { @@ -39,6 +40,9 @@ public: virtual bool IsActive(); + + virtual lldb::ThreadCollectionSP + GetBacktracesFromExtendedStopInfo(StructuredData::ObjectSP info); }; diff --git a/include/lldb/Target/JITLoaderList.h b/include/lldb/Target/JITLoaderList.h index f933a61e9952..c86043c5cf1f 100644 --- a/include/lldb/Target/JITLoaderList.h +++ b/include/lldb/Target/JITLoaderList.h @@ -10,10 +10,10 @@ #ifndef liblldb_JITLoaderList_h_ #define liblldb_JITLoaderList_h_ +#include <mutex> #include <vector> #include "lldb/lldb-forward.h" -#include "lldb/Host/Mutex.h" namespace lldb_private { @@ -52,7 +52,7 @@ public: private: std::vector<lldb::JITLoaderSP> m_jit_loaders_vec; - lldb_private::Mutex m_jit_loaders_mutex; + std::recursive_mutex m_jit_loaders_mutex; }; } // namespace lldb_private diff --git a/include/lldb/Target/Language.h b/include/lldb/Target/Language.h index 492425ec088b..d1a3ff8e6747 100644 --- a/include/lldb/Target/Language.h +++ b/include/lldb/Target/Language.h @@ -113,6 +113,9 @@ public: virtual std::unique_ptr<TypeScavenger> GetTypeScavenger (); + virtual const char* + GetLanguageSpecificTypeLookupHelp (); + // if an individual data formatter can apply to several types and cross a language boundary // it makes sense for individual languages to want to customize the printing of values of that // type by appending proper prefix/suffix information in language-specific ways diff --git a/include/lldb/Target/LanguageRuntime.h b/include/lldb/Target/LanguageRuntime.h index 686ec5ea3479..beb7a9e74876 100644 --- a/include/lldb/Target/LanguageRuntime.h +++ b/include/lldb/Target/LanguageRuntime.h @@ -22,6 +22,9 @@ #include "lldb/Core/ValueObject.h" #include "lldb/Core/Value.h" #include "lldb/Target/ExecutionContextScope.h" +#include "lldb/Expression/LLVMUserExpression.h" + +#include "clang/Basic/TargetOptions.h" namespace lldb_private { @@ -147,6 +150,22 @@ public: { } + // Called by the Clang expression evaluation engine to allow runtimes to alter the set of target options provided to + // the compiler. + // If the options prototype is modified, runtimes must return true, false otherwise. + virtual bool + GetOverrideExprOptions(clang::TargetOptions &prototype) + { + return false; + } + + // Called by ClangExpressionParser::PrepareForExecution to query for any custom LLVM IR passes + // that need to be run before an expression is assembled and run. + virtual bool + GetIRPasses(LLVMUserExpression::IRPasses &custom_passes) + { + return false; + } protected: //------------------------------------------------------------------ // Classes that inherit from LanguageRuntime can see and modify these diff --git a/include/lldb/Target/Memory.h b/include/lldb/Target/Memory.h index bf1cc1878784..f4d776a43c99 100644 --- a/include/lldb/Target/Memory.h +++ b/include/lldb/Target/Memory.h @@ -13,6 +13,7 @@ // C Includes // C++ Includes #include <map> +#include <mutex> #include <vector> // Other libraries and framework includes @@ -20,7 +21,6 @@ // Project includes #include "lldb/lldb-private.h" #include "lldb/Core/RangeMap.h" -#include "lldb/Host/Mutex.h" namespace lldb_private { //---------------------------------------------------------------------- @@ -75,7 +75,7 @@ namespace lldb_private { //------------------------------------------------------------------ // Classes that inherit from MemoryCache can see and modify these //------------------------------------------------------------------ - Mutex m_mutex; + std::recursive_mutex m_mutex; BlockMap m_L1_cache; // A first level memory cache whose chunk sizes vary that will be used only if the memory read fits entirely in a chunk BlockMap m_L2_cache; // A memory cache of fixed size chinks (m_L2_cache_line_byte_size bytes in size each) InvalidRanges m_invalid_ranges; @@ -192,7 +192,7 @@ namespace lldb_private { // Classes that inherit from MemoryCache can see and modify these //------------------------------------------------------------------ Process &m_process; - Mutex m_mutex; + std::recursive_mutex m_mutex; typedef std::multimap<uint32_t, AllocatedBlockSP> PermissionsToBlockMap; PermissionsToBlockMap m_memory_map; diff --git a/include/lldb/Target/MemoryRegionInfo.h b/include/lldb/Target/MemoryRegionInfo.h index 0726ad15e876..5c82a1f294dd 100644 --- a/include/lldb/Target/MemoryRegionInfo.h +++ b/include/lldb/Target/MemoryRegionInfo.h @@ -30,7 +30,8 @@ namespace lldb_private m_range (), m_read (eDontKnow), m_write (eDontKnow), - m_execute (eDontKnow) + m_execute (eDontKnow), + m_mapped (eDontKnow) { } @@ -75,6 +76,12 @@ namespace lldb_private return m_execute; } + OptionalBool + GetMapped () const + { + return m_mapped; + } + void SetReadable (OptionalBool val) { @@ -93,11 +100,63 @@ namespace lldb_private m_execute = val; } + void + SetMapped (OptionalBool val) + { + m_mapped = val; + } + + //---------------------------------------------------------------------- + // Get permissions as a uint32_t that is a mask of one or more bits from + // the lldb::Permissions + //---------------------------------------------------------------------- + uint32_t + GetLLDBPermissions() const + { + uint32_t permissions = 0; + if (m_read) + permissions |= lldb::ePermissionsReadable; + if (m_write) + permissions |= lldb::ePermissionsWritable; + if (m_execute) + permissions |= lldb::ePermissionsExecutable; + return permissions; + } + + //---------------------------------------------------------------------- + // Set permissions from a uint32_t that contains one or more bits from + // the lldb::Permissions + //---------------------------------------------------------------------- + void + SetLLDBPermissions(uint32_t permissions) + { + m_read = (permissions & lldb::ePermissionsReadable) ? eYes : eNo; + m_write = (permissions & lldb::ePermissionsWritable) ? eYes : eNo; + m_execute = (permissions & lldb::ePermissionsExecutable) ? eYes : eNo; + } + + bool + operator == (const MemoryRegionInfo &rhs) const + { + return m_range == rhs.m_range && + m_read == rhs.m_read && + m_write == rhs.m_write && + m_execute == rhs.m_execute && + m_mapped == rhs.m_mapped; + } + + bool + operator != (const MemoryRegionInfo &rhs) const + { + return !(*this == rhs); + } + protected: RangeType m_range; OptionalBool m_read; OptionalBool m_write; OptionalBool m_execute; + OptionalBool m_mapped; }; } diff --git a/include/lldb/Target/PathMappingList.h b/include/lldb/Target/PathMappingList.h index 17185cb68495..1a486c4642dc 100644 --- a/include/lldb/Target/PathMappingList.h +++ b/include/lldb/Target/PathMappingList.h @@ -116,7 +116,9 @@ public: bool RemapPath (const char *path, std::string &new_path) const; - + bool + ReverseRemapPath (const ConstString &path, ConstString &new_path) const; + //------------------------------------------------------------------ /// Finds a source file given a file spec using the path remappings. /// diff --git a/include/lldb/Target/Platform.h b/include/lldb/Target/Platform.h index 53c17a6a66cf..6fdd92db5680 100644 --- a/include/lldb/Target/Platform.h +++ b/include/lldb/Target/Platform.h @@ -15,6 +15,7 @@ #include <functional> #include <map> #include <memory> +#include <mutex> #include <string> #include <vector> @@ -28,7 +29,6 @@ #include "lldb/Core/UserSettingsController.h" #include "lldb/Interpreter/Options.h" #include "lldb/Host/FileSpec.h" -#include "lldb/Host/Mutex.h" // TODO pull NativeDelegate class out of NativeProcessProtocol so we // can just forward ref the NativeDelegate rather than include it here. @@ -427,7 +427,7 @@ class ModuleCache; virtual size_t GetSoftwareBreakpointTrapOpcode (Target &target, - BreakpointSite *bp_site) = 0; + BreakpointSite *bp_site); //------------------------------------------------------------------ /// Launch a new process on a platform, not necessarily for @@ -1079,7 +1079,8 @@ class ModuleCache; uint32_t m_update_os_version; ArchSpec m_system_arch; // The architecture of the kernel or the remote platform typedef std::map<uint32_t, ConstString> IDToNameMap; - Mutex m_mutex; // Mutex for modifying Platform data structures that should only be used for non-reentrant code + // Mutex for modifying Platform data structures that should only be used for non-reentrant code + std::mutex m_mutex; IDToNameMap m_uid_map; IDToNameMap m_gid_map; size_t m_max_uid_name_len; @@ -1112,9 +1113,9 @@ class ModuleCache; CalculateTrapHandlerSymbolNames () = 0; const char * - GetCachedUserName (uint32_t uid) + GetCachedUserName(uint32_t uid) { - Mutex::Locker locker (m_mutex); + std::lock_guard<std::mutex> guard(m_mutex); // return the empty string if our string is NULL // so we can tell when things were in the negative // cached (didn't find a valid user name, don't keep @@ -1124,35 +1125,35 @@ class ModuleCache; } const char * - SetCachedUserName (uint32_t uid, const char *name, size_t name_len) + SetCachedUserName(uint32_t uid, const char *name, size_t name_len) { - Mutex::Locker locker (m_mutex); - ConstString const_name (name); + std::lock_guard<std::mutex> guard(m_mutex); + ConstString const_name(name); m_uid_map[uid] = const_name; if (m_max_uid_name_len < name_len) m_max_uid_name_len = name_len; // Const strings lives forever in our const string pool, so we can return the const char * - return const_name.GetCString(); + return const_name.GetCString(); } void - SetUserNameNotFound (uint32_t uid) + SetUserNameNotFound(uint32_t uid) { - Mutex::Locker locker (m_mutex); + std::lock_guard<std::mutex> guard(m_mutex); m_uid_map[uid] = ConstString(); } void - ClearCachedUserNames () + ClearCachedUserNames() { - Mutex::Locker locker (m_mutex); + std::lock_guard<std::mutex> guard(m_mutex); m_uid_map.clear(); } - + const char * - GetCachedGroupName (uint32_t gid) + GetCachedGroupName(uint32_t gid) { - Mutex::Locker locker (m_mutex); + std::lock_guard<std::mutex> guard(m_mutex); // return the empty string if our string is NULL // so we can tell when things were in the negative // cached (didn't find a valid group name, don't keep @@ -1162,28 +1163,28 @@ class ModuleCache; } const char * - SetCachedGroupName (uint32_t gid, const char *name, size_t name_len) + SetCachedGroupName(uint32_t gid, const char *name, size_t name_len) { - Mutex::Locker locker (m_mutex); - ConstString const_name (name); + std::lock_guard<std::mutex> guard(m_mutex); + ConstString const_name(name); m_gid_map[gid] = const_name; if (m_max_gid_name_len < name_len) m_max_gid_name_len = name_len; // Const strings lives forever in our const string pool, so we can return the const char * - return const_name.GetCString(); + return const_name.GetCString(); } void - SetGroupNameNotFound (uint32_t gid) + SetGroupNameNotFound(uint32_t gid) { - Mutex::Locker locker (m_mutex); + std::lock_guard<std::mutex> guard(m_mutex); m_gid_map[gid] = ConstString(); } void - ClearCachedGroupNames () + ClearCachedGroupNames() { - Mutex::Locker locker (m_mutex); + std::lock_guard<std::mutex> guard(m_mutex); m_gid_map.clear(); } @@ -1236,20 +1237,15 @@ class ModuleCache; class PlatformList { public: - PlatformList() : - m_mutex (Mutex::eMutexTypeRecursive), - m_platforms (), - m_selected_platform_sp() - { - } + PlatformList() : m_mutex(), m_platforms(), m_selected_platform_sp() {} ~PlatformList() = default; void - Append (const lldb::PlatformSP &platform_sp, bool set_selected) + Append(const lldb::PlatformSP &platform_sp, bool set_selected) { - Mutex::Locker locker (m_mutex); - m_platforms.push_back (platform_sp); + std::lock_guard<std::recursive_mutex> guard(m_mutex); + m_platforms.push_back(platform_sp); if (set_selected) m_selected_platform_sp = m_platforms.back(); } @@ -1257,16 +1253,16 @@ class ModuleCache; size_t GetSize() { - Mutex::Locker locker (m_mutex); + std::lock_guard<std::recursive_mutex> guard(m_mutex); return m_platforms.size(); } lldb::PlatformSP - GetAtIndex (uint32_t idx) + GetAtIndex(uint32_t idx) { lldb::PlatformSP platform_sp; { - Mutex::Locker locker (m_mutex); + std::lock_guard<std::recursive_mutex> guard(m_mutex); if (idx < m_platforms.size()) platform_sp = m_platforms[idx]; } @@ -1283,23 +1279,23 @@ class ModuleCache; /// processes. //------------------------------------------------------------------ lldb::PlatformSP - GetSelectedPlatform () + GetSelectedPlatform() { - Mutex::Locker locker (m_mutex); + std::lock_guard<std::recursive_mutex> guard(m_mutex); if (!m_selected_platform_sp && !m_platforms.empty()) m_selected_platform_sp = m_platforms.front(); - + return m_selected_platform_sp; } void - SetSelectedPlatform (const lldb::PlatformSP &platform_sp) + SetSelectedPlatform(const lldb::PlatformSP &platform_sp) { if (platform_sp) { - Mutex::Locker locker (m_mutex); + std::lock_guard<std::recursive_mutex> guard(m_mutex); const size_t num_platforms = m_platforms.size(); - for (size_t idx=0; idx<num_platforms; ++idx) + for (size_t idx = 0; idx < num_platforms; ++idx) { if (m_platforms[idx].get() == platform_sp.get()) { @@ -1307,28 +1303,28 @@ class ModuleCache; return; } } - m_platforms.push_back (platform_sp); + m_platforms.push_back(platform_sp); m_selected_platform_sp = m_platforms.back(); } } protected: typedef std::vector<lldb::PlatformSP> collection; - mutable Mutex m_mutex; + mutable std::recursive_mutex m_mutex; collection m_platforms; lldb::PlatformSP m_selected_platform_sp; private: DISALLOW_COPY_AND_ASSIGN (PlatformList); }; - + class OptionGroupPlatformRSync : public lldb_private::OptionGroup { public: - OptionGroupPlatformRSync (); - - ~OptionGroupPlatformRSync() override; - + OptionGroupPlatformRSync() = default; + + ~OptionGroupPlatformRSync() override = default; + lldb_private::Error SetOptionValue(CommandInterpreter &interpreter, uint32_t option_idx, @@ -1353,6 +1349,7 @@ class ModuleCache; std::string m_rsync_opts; std::string m_rsync_prefix; bool m_ignores_remote_hostname; + private: DISALLOW_COPY_AND_ASSIGN(OptionGroupPlatformRSync); }; @@ -1360,10 +1357,10 @@ class ModuleCache; class OptionGroupPlatformSSH : public lldb_private::OptionGroup { public: - OptionGroupPlatformSSH (); - - ~OptionGroupPlatformSSH() override; - + OptionGroupPlatformSSH() = default; + + ~OptionGroupPlatformSSH() override = default; + lldb_private::Error SetOptionValue(CommandInterpreter &interpreter, uint32_t option_idx, @@ -1394,10 +1391,10 @@ class ModuleCache; class OptionGroupPlatformCaching : public lldb_private::OptionGroup { public: - OptionGroupPlatformCaching (); - - ~OptionGroupPlatformCaching() override; - + OptionGroupPlatformCaching() = default; + + ~OptionGroupPlatformCaching() override = default; + lldb_private::Error SetOptionValue(CommandInterpreter &interpreter, uint32_t option_idx, diff --git a/include/lldb/Target/Process.h b/include/lldb/Target/Process.h index 6bb7a3d783de..57787f2f8f39 100644 --- a/include/lldb/Target/Process.h +++ b/include/lldb/Target/Process.h @@ -18,6 +18,7 @@ // C++ Includes #include <list> #include <memory> +#include <mutex> #include <string> #include <vector> #include <unordered_set> @@ -30,6 +31,7 @@ #include "lldb/Core/Communication.h" #include "lldb/Core/Error.h" #include "lldb/Core/Event.h" +#include "lldb/Core/Listener.h" #include "lldb/Core/LoadedModuleInfoList.h" #include "lldb/Core/ThreadSafeValue.h" #include "lldb/Core/PluginInterface.h" @@ -400,7 +402,7 @@ public: m_listener_sp = listener_sp; } - Listener & + lldb::ListenerSP GetListenerForProcess (Debugger &debugger); protected: @@ -939,13 +941,13 @@ public: /// Construct with a shared pointer to a target, and the Process listener. /// Uses the Host UnixSignalsSP by default. //------------------------------------------------------------------ - Process(lldb::TargetSP target_sp, Listener &listener); + Process(lldb::TargetSP target_sp, lldb::ListenerSP listener_sp); //------------------------------------------------------------------ /// Construct with a shared pointer to a target, the Process listener, /// and the appropriate UnixSignalsSP for the process. //------------------------------------------------------------------ - Process(lldb::TargetSP target_sp, Listener &listener, const lldb::UnixSignalsSP &unix_signals_sp); + Process(lldb::TargetSP target_sp, lldb::ListenerSP listener_sp, const lldb::UnixSignalsSP &unix_signals_sp); //------------------------------------------------------------------ /// Destructor. @@ -985,7 +987,7 @@ public: static lldb::ProcessSP FindPlugin (lldb::TargetSP target_sp, const char *plugin_name, - Listener &listener, + lldb::ListenerSP listener_sp, const FileSpec *crash_file_path); //------------------------------------------------------------------ @@ -998,16 +1000,14 @@ public: /// Subclasses should call Host::StartMonitoringChildProcess () /// with: /// callback = Process::SetHostProcessExitStatus - /// callback_baton = nullptr /// pid = Process::GetID() /// monitor_signals = false //------------------------------------------------------------------ static bool - SetProcessExitStatus(void *callback_baton, // The callback baton which should be set to nullptr - lldb::pid_t pid, // The process ID we want to monitor + SetProcessExitStatus(lldb::pid_t pid, // The process ID we want to monitor bool exited, - int signo, // Zero for no signal - int status); // Exit value of process if signal is zero + int signo, // Zero for no signal + int status); // Exit value of process if signal is zero lldb::ByteOrder GetByteOrder () const; @@ -1886,15 +1886,13 @@ public: //------------------------------------------------------------------ lldb::StateType GetState (); - + lldb::ExpressionResults - RunThreadPlan (ExecutionContext &exe_ctx, - lldb::ThreadPlanSP &thread_plan_sp, - const EvaluateExpressionOptions &options, - Stream &errors); + RunThreadPlan(ExecutionContext &exe_ctx, lldb::ThreadPlanSP &thread_plan_sp, + const EvaluateExpressionOptions &options, DiagnosticManager &diagnostic_manager); static const char * - ExecutionResultAsCString (lldb::ExpressionResults result); + ExecutionResultAsCString(lldb::ExpressionResults result); void GetStatus (Stream &ostrm); @@ -1962,6 +1960,9 @@ public: void PrintWarningOptimization (const SymbolContext &sc); + virtual bool + GetProcessInfo(ProcessInstanceInfo &info); + public: //------------------------------------------------------------------ /// Get the exit status for a process. @@ -2232,11 +2233,11 @@ public: /// order. //------------------------------------------------------------------ uint64_t - ReadUnsignedIntegerFromMemory (lldb::addr_t load_addr, - size_t byte_size, - uint64_t fail_value, - Error &error); - + ReadUnsignedIntegerFromMemory(lldb::addr_t load_addr, size_t byte_size, uint64_t fail_value, Error &error); + + int64_t + ReadSignedIntegerFromMemory(lldb::addr_t load_addr, size_t byte_size, int64_t fail_value, Error &error); + lldb::addr_t ReadPointerFromMemory (lldb::addr_t vm_addr, Error &error); @@ -2436,6 +2437,32 @@ public: virtual lldb::addr_t ResolveIndirectFunction(const Address *address, Error &error); + //------------------------------------------------------------------ + /// Locate the memory region that contains load_addr. + /// + /// If load_addr is within the address space the process has mapped + /// range_info will be filled in with the start and end of that range + /// as well as the permissions for that range and range_info.GetMapped + /// will return true. + /// + /// If load_addr is outside any mapped region then range_info will + /// have its start address set to load_addr and the end of the + /// range will indicate the start of the next mapped range or be + /// set to LLDB_INVALID_ADDRESS if there are no valid mapped ranges + /// between load_addr and the end of the process address space. + /// + /// GetMemoryRegionInfo will only return an error if it is + /// unimplemented for the current process. + /// + /// @param[in] load_addr + /// The load address to query the range_info for. + /// + /// @param[out] range_info + /// An range_info value containing the details of the range. + /// + /// @return + /// An error value. + //------------------------------------------------------------------ virtual Error GetMemoryRegionInfo (lldb::addr_t load_addr, MemoryRegionInfo &range_info) @@ -2445,6 +2472,19 @@ public: return error; } + //------------------------------------------------------------------ + /// Obtain all the mapped memory regions within this process. + /// + /// @param[out] region_list + /// A vector to contain MemoryRegionInfo objects for all mapped + /// ranges. + /// + /// @return + /// An error value. + //------------------------------------------------------------------ + virtual Error + GetMemoryRegions (std::vector<lldb::MemoryRegionInfoSP>& region_list); + virtual Error GetWatchpointSupportInfo (uint32_t &num) { @@ -2851,7 +2891,7 @@ public: WaitForProcessToStop(const TimeValue *timeout, lldb::EventSP *event_sp_ptr = nullptr, bool wait_always = true, - Listener *hijack_listener = nullptr, + lldb::ListenerSP hijack_listener = lldb::ListenerSP(), Stream *stream = nullptr, bool use_run_lock = true); @@ -2877,7 +2917,7 @@ public: lldb::StateType WaitForStateChangedEvents(const TimeValue *timeout, lldb::EventSP &event_sp, - Listener *hijack_listener); // Pass nullptr to use builtin listener + lldb::ListenerSP hijack_listener); // Pass an empty ListenerSP to use builtin listener //-------------------------------------------------------------------------------------- /// Centralize the code that handles and prints descriptions for process state changes. @@ -2908,10 +2948,10 @@ public: ProcessEventHijacker { public: - ProcessEventHijacker (Process &process, Listener *listener) : + ProcessEventHijacker (Process &process, lldb::ListenerSP listener_sp) : m_process (process) { - m_process.HijackProcessEvents (listener); + m_process.HijackProcessEvents (listener_sp); } ~ProcessEventHijacker () @@ -2940,7 +2980,7 @@ public: /// \b false otherwise. //------------------------------------------------------------------ bool - HijackProcessEvents (Listener *listener); + HijackProcessEvents (lldb::ListenerSP listener_sp); //------------------------------------------------------------------ /// Restores the process event broadcasting to its normal state. @@ -3308,9 +3348,13 @@ protected: bool PrivateStateThreadIsValid () const { - return m_private_state_thread.IsJoinable(); + lldb::StateType state = m_private_state.GetValue(); + return state != lldb::eStateInvalid && + state != lldb::eStateDetached && + state != lldb::eStateExited && + m_private_state_thread.IsJoinable(); } - + void ForceNextEventDelivery() { @@ -3343,8 +3387,7 @@ protected: ThreadSafeValue<lldb::StateType> m_private_state; // The actual state of our process Broadcaster m_private_state_broadcaster; // This broadcaster feeds state changed events into the private state thread's listener. Broadcaster m_private_state_control_broadcaster; // This is the control broadcaster, used to pause, resume & stop the private state thread. - Listener m_private_state_listener; // This is the listener for the private state thread. - Predicate<bool> m_private_state_control_wait; /// This Predicate is used to signal that a control operation is complete. + lldb::ListenerSP m_private_state_listener_sp; // This is the listener for the private state thread. HostThread m_private_state_thread; ///< Thread ID for the thread that watches internal state events ProcessModID m_mod_id; ///< Tracks the state of the process over stops and other alterations. uint32_t m_process_unique_id; ///< Each lldb_private::Process class that is created gets a unique integer ID that increments with each new instance @@ -3352,8 +3395,9 @@ protected: std::map<uint64_t, uint32_t> m_thread_id_to_index_id_map; int m_exit_status; ///< The exit status of the process, or -1 if not set. std::string m_exit_string; ///< A textual description of why a process exited. - Mutex m_exit_status_mutex; ///< Mutex so m_exit_status m_exit_string can be safely accessed from multiple threads - Mutex m_thread_mutex; + std::mutex + m_exit_status_mutex; ///< Mutex so m_exit_status m_exit_string can be safely accessed from multiple threads + std::recursive_mutex m_thread_mutex; ThreadList m_thread_list_real; ///< The threads for this process as are known to the protocol we are debugging with ThreadList m_thread_list; ///< The threads for this process as the user will see them. This is usually the same as ///< m_thread_list_real, but might be different if there is an OS plug-in creating memory threads @@ -3363,7 +3407,7 @@ protected: uint32_t m_queue_list_stop_id; ///< The natural stop id when queue list was last fetched std::vector<Notifications> m_notifications; ///< The list of notifications that this process can deliver. std::vector<lldb::addr_t> m_image_tokens; - Listener &m_listener; + lldb::ListenerSP m_listener_sp; ///< Shared pointer to the listener used for public events. Can not be empty. BreakpointSiteList m_breakpoint_site_list; ///< This is the list of breakpoint locations we intend to insert in the target. lldb::DynamicLoaderUP m_dyld_ap; lldb::JITLoaderListUP m_jit_loaders_ap; @@ -3374,11 +3418,11 @@ protected: lldb::ABISP m_abi_sp; lldb::IOHandlerSP m_process_input_reader; Communication m_stdio_communication; - Mutex m_stdio_communication_mutex; + std::recursive_mutex m_stdio_communication_mutex; bool m_stdin_forward; /// Remember if stdin must be forwarded to remote debug server std::string m_stdout_data; std::string m_stderr_data; - Mutex m_profile_data_comm_mutex; + std::recursive_mutex m_profile_data_comm_mutex; std::vector<std::string> m_profile_data; Predicate<uint32_t> m_iohandler_sync; MemoryCache m_memory_cache; @@ -3402,6 +3446,7 @@ protected: bool m_destroy_in_process; bool m_can_interpret_function_calls; // Some targets, e.g the OSX kernel, don't support the ability to modify the stack. WarningsCollection m_warnings_issued; // A set of object pointers which have already had warnings printed + std::mutex m_run_thread_plan_lock; enum { eCanJITDontKnow= 0, @@ -3433,12 +3478,15 @@ protected: void ResumePrivateStateThread (); +private: struct PrivateStateThreadArgs { + PrivateStateThreadArgs(Process *p, bool s) : process(p), is_secondary_thread(s) {}; Process *process; bool is_secondary_thread; }; - + + // arg is a pointer to a new'ed PrivateStateThreadArgs structure. PrivateStateThread will free it for you. static lldb::thread_result_t PrivateStateThread (void *arg); @@ -3450,6 +3498,7 @@ protected: lldb::thread_result_t RunPrivateStateThread (bool is_secondary_thread); +protected: void HandlePrivateEvent (lldb::EventSP &event_sp); diff --git a/include/lldb/Target/ProcessLaunchInfo.h b/include/lldb/Target/ProcessLaunchInfo.h index 92a3ed40736d..d1a45794b551 100644 --- a/include/lldb/Target/ProcessLaunchInfo.h +++ b/include/lldb/Target/ProcessLaunchInfo.h @@ -148,9 +148,7 @@ namespace lldb_private int32_t num_resumes); void - SetMonitorProcessCallback (Host::MonitorChildProcessCallback callback, - void *baton, - bool monitor_signals); + SetMonitorProcessCallback(const Host::MonitorChildProcessCallback &callback, bool monitor_signals); Host::MonitorChildProcessCallback GetMonitorProcessCallback() const @@ -158,12 +156,6 @@ namespace lldb_private return m_monitor_callback; } - void * - GetMonitorProcessBaton() const - { - return m_monitor_callback_baton; - } - bool GetMonitorSignals() const { @@ -196,7 +188,7 @@ namespace lldb_private m_listener_sp = listener_sp; } - Listener & + lldb::ListenerSP GetListenerForProcess (Debugger &debugger); lldb::ListenerSP diff --git a/include/lldb/Target/QueueList.h b/include/lldb/Target/QueueList.h index 12a0ea52d7f4..265145db2696 100644 --- a/include/lldb/Target/QueueList.h +++ b/include/lldb/Target/QueueList.h @@ -10,6 +10,7 @@ #ifndef liblldb_QueueList_h_ #define liblldb_QueueList_h_ +#include <mutex> #include <vector> #include "lldb/lldb-private.h" @@ -60,7 +61,7 @@ public: GetQueueAtIndex (uint32_t idx); typedef std::vector<lldb::QueueSP> collection; - typedef LockingAdaptedIterable<collection, lldb::QueueSP, vector_adapter> QueueIterable; + typedef LockingAdaptedIterable<collection, lldb::QueueSP, vector_adapter, std::mutex> QueueIterable; //------------------------------------------------------------------ /// Iterate over the list of queues @@ -119,8 +120,8 @@ public: lldb::QueueSP FindQueueByIndexID (uint32_t index_id); - lldb_private::Mutex & - GetMutex (); + std::mutex & + GetMutex(); protected: @@ -130,7 +131,7 @@ protected: Process *m_process; ///< The process that manages this queue list. uint32_t m_stop_id; ///< The process stop ID that this queue list is valid for. collection m_queues; ///< The queues for this process. - Mutex m_mutex; + std::mutex m_mutex; private: QueueList (); diff --git a/include/lldb/Target/SectionLoadHistory.h b/include/lldb/Target/SectionLoadHistory.h index ddf46a1861ca..2494b7fd2779 100644 --- a/include/lldb/Target/SectionLoadHistory.h +++ b/include/lldb/Target/SectionLoadHistory.h @@ -13,10 +13,10 @@ // C Includes // C++ Includes #include <map> +#include <mutex> // Project includes #include "lldb/lldb-public.h" -#include "lldb/Host/Mutex.h" namespace lldb_private { @@ -31,11 +31,7 @@ public: //------------------------------------------------------------------ // Constructors and Destructors //------------------------------------------------------------------ - SectionLoadHistory () : - m_stop_id_to_section_load_list(), - m_mutex (Mutex::eMutexTypeRecursive) - { - } + SectionLoadHistory() : m_stop_id_to_section_load_list(), m_mutex() {} ~SectionLoadHistory() { @@ -98,7 +94,7 @@ protected: typedef std::map<uint32_t, lldb::SectionLoadListSP> StopIDToSectionLoadList; StopIDToSectionLoadList m_stop_id_to_section_load_list; - mutable Mutex m_mutex; + mutable std::recursive_mutex m_mutex; private: DISALLOW_COPY_AND_ASSIGN (SectionLoadHistory); diff --git a/include/lldb/Target/SectionLoadList.h b/include/lldb/Target/SectionLoadList.h index 5f5d39e2b24b..1326d6007f2d 100644 --- a/include/lldb/Target/SectionLoadList.h +++ b/include/lldb/Target/SectionLoadList.h @@ -13,13 +13,13 @@ // C Includes // C++ Includes #include <map> +#include <mutex> // Other libraries and framework includes #include "llvm/ADT/DenseMap.h" // Project includes #include "lldb/lldb-public.h" #include "lldb/Core/Section.h" -#include "lldb/Host/Mutex.h" namespace lldb_private { @@ -29,13 +29,7 @@ public: //------------------------------------------------------------------ // Constructors and Destructors //------------------------------------------------------------------ - SectionLoadList () : - m_addr_to_sect (), - m_sect_to_addr (), - m_mutex (Mutex::eMutexTypeRecursive) - - { - } + SectionLoadList() : m_addr_to_sect(), m_sect_to_addr(), m_mutex() {} SectionLoadList (const SectionLoadList& rhs); @@ -84,7 +78,7 @@ protected: typedef llvm::DenseMap<const Section *, lldb::addr_t> sect_to_addr_collection; addr_to_sect_collection m_addr_to_sect; sect_to_addr_collection m_sect_to_addr; - mutable Mutex m_mutex; + mutable std::recursive_mutex m_mutex; }; } // namespace lldb_private diff --git a/include/lldb/Target/StackFrame.h b/include/lldb/Target/StackFrame.h index b65b01810176..b3cc57f176ca 100644 --- a/include/lldb/Target/StackFrame.h +++ b/include/lldb/Target/StackFrame.h @@ -13,6 +13,7 @@ // C Includes // C++ Includes #include <memory> +#include <mutex> // Other libraries and framework includes // Project includes @@ -289,7 +290,7 @@ public: /// A pointer to a list of variables. //------------------------------------------------------------------ lldb::VariableListSP - GetInScopeVariableList (bool get_file_globals); + GetInScopeVariableList (bool get_file_globals, bool must_have_valid_location = false); //------------------------------------------------------------------ /// Create a ValueObject for a variable name / pathname, possibly @@ -478,6 +479,11 @@ public: lldb::LanguageType GetLanguage (); + // similar to GetLanguage(), but is allowed to take a potentially incorrect guess + // if exact information is not available + lldb::LanguageType + GuessLanguage (); + //------------------------------------------------------------------ // lldb::ExecutionContextScope pure virtual functions //------------------------------------------------------------------ @@ -532,7 +538,7 @@ private: lldb::VariableListSP m_variable_list_sp; ValueObjectList m_variable_list_value_objects; // Value objects for each variable in m_variable_list_sp StreamString m_disassembly; - Mutex m_mutex; + std::recursive_mutex m_mutex; DISALLOW_COPY_AND_ASSIGN (StackFrame); }; diff --git a/include/lldb/Target/StackFrameList.h b/include/lldb/Target/StackFrameList.h index 50a656de9e69..8b6bea3193c5 100644 --- a/include/lldb/Target/StackFrameList.h +++ b/include/lldb/Target/StackFrameList.h @@ -13,11 +13,11 @@ // C Includes // C++ Includes #include <memory> +#include <mutex> #include <vector> // Other libraries and framework includes // Project includes -#include "lldb/Host/Mutex.h" #include "lldb/Target/StackFrame.h" namespace lldb_private { @@ -135,7 +135,7 @@ protected: Thread &m_thread; lldb::StackFrameListSP m_prev_frames_sp; - mutable Mutex m_mutex; + mutable std::recursive_mutex m_mutex; collection m_frames; uint32_t m_selected_frame_idx; uint32_t m_concrete_frames_fetched; diff --git a/include/lldb/Target/Target.h b/include/lldb/Target/Target.h index 0cdb248a9b44..7124b2e83467 100644 --- a/include/lldb/Target/Target.h +++ b/include/lldb/Target/Target.h @@ -53,9 +53,22 @@ typedef enum LoadScriptFromSymFile eLoadScriptFromSymFileWarn } LoadScriptFromSymFile; +typedef enum LoadCWDlldbinitFile +{ + eLoadCWDlldbinitTrue, + eLoadCWDlldbinitFalse, + eLoadCWDlldbinitWarn +} LoadCWDlldbinitFile; + //---------------------------------------------------------------------- // TargetProperties //---------------------------------------------------------------------- +class TargetExperimentalProperties : public Properties +{ +public: + TargetExperimentalProperties(); +}; + class TargetProperties : public Properties { public: @@ -142,6 +155,12 @@ public: GetEnableAutoImportClangModules () const; bool + GetEnableAutoApplyFixIts () const; + + bool + GetEnableNotifyAboutFixIts () const; + + bool GetEnableSyntheticValue () const; uint32_t @@ -192,6 +211,9 @@ public: LoadScriptFromSymFile GetLoadScriptFromSymbolFile() const; + LoadCWDlldbinitFile + GetLoadCWDlldbinitFile () const; + Disassembler::HexImmediateStyle GetHexImmediateStyle() const; @@ -221,6 +243,12 @@ public: void SetProcessLaunchInfo(const ProcessLaunchInfo &launch_info); + + bool + GetInjectLocalVariables(ExecutionContext *exe_ctx) const; + + void + SetInjectLocalVariables(ExecutionContext *exe_ctx, bool b); private: //------------------------------------------------------------------ @@ -241,14 +269,17 @@ private: // Member variables. //------------------------------------------------------------------ ProcessLaunchInfo m_launch_info; + std::unique_ptr<TargetExperimentalProperties> m_experimental_properties_up; }; class EvaluateExpressionOptions { public: static const uint32_t default_timeout = 500000; + static const ExecutionPolicy default_execution_policy = eExecutionPolicyOnlyWhenNeeded; + EvaluateExpressionOptions() : - m_execution_policy(eExecutionPolicyOnlyWhenNeeded), + m_execution_policy(default_execution_policy), m_language (lldb::eLanguageTypeUnknown), m_prefix (), // A prefix specific to this expression that is added after the prefix from the settings (if any) m_coerce_to_id (false), @@ -261,6 +292,7 @@ public: m_trap_exceptions (true), m_generate_debug_info (false), m_result_is_internal (false), + m_auto_apply_fixits (true), m_use_dynamic (lldb::eNoDynamicValues), m_timeout_usec (default_timeout), m_one_thread_timeout_usec (0), @@ -531,6 +563,18 @@ public: { return m_result_is_internal; } + + void + SetAutoApplyFixIts(bool b) + { + m_auto_apply_fixits = b; + } + + bool + GetAutoApplyFixIts() const + { + return m_auto_apply_fixits; + } private: ExecutionPolicy m_execution_policy; @@ -548,6 +592,7 @@ private: bool m_generate_debug_info; bool m_ansi_color_errors; bool m_result_is_internal; + bool m_auto_apply_fixits; lldb::DynamicValueType m_use_dynamic; uint32_t m_timeout_usec; uint32_t m_one_thread_timeout_usec; @@ -681,8 +726,8 @@ public: static const lldb::TargetPropertiesSP & GetGlobalProperties(); - Mutex & - GetAPIMutex () + std::recursive_mutex & + GetAPIMutex() { return m_mutex; } @@ -709,7 +754,7 @@ public: Dump (Stream *s, lldb::DescriptionLevel description_level); const lldb::ProcessSP & - CreateProcess (Listener &listener, + CreateProcess (lldb::ListenerSP listener, const char *plugin_name, const FileSpec *crash_file); @@ -757,6 +802,7 @@ public: CreateBreakpoint (const FileSpecList *containingModules, const FileSpec &file, uint32_t line_no, + lldb::addr_t offset, LazyBool check_inlines, LazyBool skip_prologue, bool internal, @@ -764,9 +810,11 @@ public: LazyBool move_to_nearest_code); // Use this to create breakpoint that matches regex against the source lines in files given in source_file_list: + // If function_names is non-empty, also filter by function after the matches are made. lldb::BreakpointSP CreateSourceRegexBreakpoint (const FileSpecList *containingModules, const FileSpecList *source_file_list, + const std::unordered_set<std::string> &function_names, RegularExpression &source_regex, bool internal, bool request_hardware, @@ -813,6 +861,7 @@ public: const char *func_name, uint32_t func_name_type_mask, lldb::LanguageType language, + lldb::addr_t offset, LazyBool skip_prologue, bool internal, bool request_hardware); @@ -834,8 +883,9 @@ public: const FileSpecList *containingSourceFiles, const char *func_names[], size_t num_names, - uint32_t func_name_type_mask, + uint32_t func_name_type_mask, lldb::LanguageType language, + lldb::addr_t offset, LazyBool skip_prologue, bool internal, bool request_hardware); @@ -846,6 +896,7 @@ public: const std::vector<std::string> &func_names, uint32_t func_name_type_mask, lldb::LanguageType language, + lldb::addr_t m_offset, LazyBool skip_prologue, bool internal, bool request_hardware); @@ -1342,7 +1393,8 @@ public: EvaluateExpression (const char *expression, ExecutionContextScope *exe_scope, lldb::ValueObjectSP &result_valobj_sp, - const EvaluateExpressionOptions& options = EvaluateExpressionOptions()); + const EvaluateExpressionOptions& options = EvaluateExpressionOptions(), + std::string *fixed_expression = nullptr); lldb::ExpressionVariableSP GetPersistentVariable(const ConstString &name); @@ -1555,7 +1607,8 @@ protected: //------------------------------------------------------------------ Debugger & m_debugger; lldb::PlatformSP m_platform_sp; ///< The platform for this target. - Mutex m_mutex; ///< An API mutex that is used by the lldb::SB* classes make the SB interface thread safe + std::recursive_mutex + m_mutex; ///< An API mutex that is used by the lldb::SB* classes make the SB interface thread safe ArchSpec m_arch; ModuleList m_images; ///< The list of images for this process (shared libraries and anything dynamically loaded). SectionLoadHistory m_section_load_history; diff --git a/include/lldb/Target/TargetList.h b/include/lldb/Target/TargetList.h index fddb715b46f3..d96d2f1b0e7a 100644 --- a/include/lldb/Target/TargetList.h +++ b/include/lldb/Target/TargetList.h @@ -12,12 +12,12 @@ // C Includes // C++ Includes +#include <mutex> #include <vector> // Other libraries and framework includes // Project includes #include "lldb/Core/Broadcaster.h" -#include "lldb/Host/Mutex.h" #include "lldb/Target/Target.h" namespace lldb_private { @@ -229,7 +229,7 @@ protected: //------------------------------------------------------------------ collection m_target_list; lldb::TargetSP m_dummy_target_sp; - mutable Mutex m_target_list_mutex; + mutable std::recursive_mutex m_target_list_mutex; uint32_t m_selected_target_idx; private: diff --git a/include/lldb/Target/Thread.h b/include/lldb/Target/Thread.h index ba73e0b49da8..f3cf97325e16 100644 --- a/include/lldb/Target/Thread.h +++ b/include/lldb/Target/Thread.h @@ -13,13 +13,13 @@ // C Includes // C++ Includes #include <memory> +#include <mutex> #include <string> #include <vector> // Other libraries and framework includes // Project includes #include "lldb/lldb-private.h" -#include "lldb/Host/Mutex.h" #include "lldb/Core/Broadcaster.h" #include "lldb/Core/Event.h" #include "lldb/Core/StructuredData.h" @@ -708,13 +708,15 @@ public: /// @param[in] module /// The module to query TLS data for. /// + /// @param[in] tls_file_addr + /// The thread local address in module /// @return /// If the thread has TLS data allocated for the /// module, the address of the TLS block. Otherwise /// LLDB_INVALID_ADDRESS is returned. //------------------------------------------------------------------ virtual lldb::addr_t - GetThreadLocalData (const lldb::ModuleSP module); + GetThreadLocalData(const lldb::ModuleSP module, lldb::addr_t tls_file_addr); //------------------------------------------------------------------ /// Check whether this thread is safe to run functions @@ -1446,11 +1448,11 @@ protected: const uint32_t m_index_id; ///< A unique 1 based index assigned to each thread for easy UI/command line access. lldb::RegisterContextSP m_reg_context_sp; ///< The register context for this thread's current register state. lldb::StateType m_state; ///< The state of our process. - mutable Mutex m_state_mutex; ///< Multithreaded protection for m_state. + mutable std::recursive_mutex m_state_mutex; ///< Multithreaded protection for m_state. plan_stack m_plan_stack; ///< The stack of plans this thread is executing. plan_stack m_completed_plan_stack; ///< Plans that have been completed by this stop. They get deleted when the thread resumes. plan_stack m_discarded_plan_stack; ///< Plans that have been discarded by this stop. They get deleted when the thread resumes. - mutable Mutex m_frame_mutex; ///< Multithreaded protection for m_state. + mutable std::recursive_mutex m_frame_mutex; ///< Multithreaded protection for m_state. lldb::StackFrameListSP m_curr_frames_sp; ///< The stack frames that get lazily populated after a thread stops. lldb::StackFrameListSP m_prev_frames_sp; ///< The previous stack frames from the last time this thread stopped. int m_resume_signal; ///< The signal that should be used when continuing this thread. diff --git a/include/lldb/Target/ThreadCollection.h b/include/lldb/Target/ThreadCollection.h index 0c2b41cc0ca4..f24167f120a8 100644 --- a/include/lldb/Target/ThreadCollection.h +++ b/include/lldb/Target/ThreadCollection.h @@ -10,10 +10,10 @@ #ifndef liblldb_ThreadCollection_h_ #define liblldb_ThreadCollection_h_ +#include <mutex> #include <vector> #include "lldb/lldb-private.h" -#include "lldb/Host/Mutex.h" #include "lldb/Utility/Iterable.h" namespace lldb_private { @@ -22,8 +22,8 @@ class ThreadCollection { public: typedef std::vector<lldb::ThreadSP> collection; - typedef LockingAdaptedIterable<collection, lldb::ThreadSP, vector_adapter> ThreadIterable; - + typedef LockingAdaptedIterable<collection, lldb::ThreadSP, vector_adapter, std::recursive_mutex> ThreadIterable; + ThreadCollection(); ThreadCollection(collection threads); @@ -38,7 +38,10 @@ public: void AddThread (const lldb::ThreadSP &thread_sp); - + + void + AddThreadSortedByIndexID (const lldb::ThreadSP &thread_sp); + void InsertThread (const lldb::ThreadSP &thread_sp, uint32_t idx); @@ -53,16 +56,16 @@ public: { return ThreadIterable(m_threads, GetMutex()); } - - virtual Mutex & + + virtual std::recursive_mutex & GetMutex() { return m_mutex; } - + protected: collection m_threads; - Mutex m_mutex; + std::recursive_mutex m_mutex; }; } // namespace lldb_private diff --git a/include/lldb/Target/ThreadList.h b/include/lldb/Target/ThreadList.h index e6489b25e558..140fdaa444d0 100644 --- a/include/lldb/Target/ThreadList.h +++ b/include/lldb/Target/ThreadList.h @@ -10,12 +10,14 @@ #ifndef liblldb_ThreadList_h_ #define liblldb_ThreadList_h_ +#include <mutex> #include <vector> #include "lldb/lldb-private.h" #include "lldb/Core/UserID.h" #include "lldb/Utility/Iterable.h" #include "lldb/Target/ThreadCollection.h" +#include "lldb/Target/Thread.h" namespace lldb_private { @@ -44,7 +46,43 @@ public: // selected at index 0. lldb::ThreadSP GetSelectedThread (); + + // Manage the thread to use for running expressions. This is usually the Selected thread, + // but sometimes (e.g. when evaluating breakpoint conditions & stop hooks) it isn't. + class ExpressionExecutionThreadPusher + { + public: + ExpressionExecutionThreadPusher(ThreadList &thread_list, lldb::tid_t tid) : + m_thread_list(&thread_list), + m_tid(tid) + { + m_thread_list->PushExpressionExecutionThread(m_tid); + } + + ExpressionExecutionThreadPusher(lldb::ThreadSP thread_sp); + + ~ExpressionExecutionThreadPusher() + { + if (m_thread_list && m_tid != LLDB_INVALID_THREAD_ID) + m_thread_list->PopExpressionExecutionThread(m_tid); + } + + private: + ThreadList *m_thread_list; + lldb::tid_t m_tid; + }; + lldb::ThreadSP + GetExpressionExecutionThread(); + +protected: + void + PushExpressionExecutionThread(lldb::tid_t tid); + + void + PopExpressionExecutionThread(lldb::tid_t tid); + +public: bool SetSelectedThreadByID (lldb::tid_t tid, bool notify = false); @@ -127,9 +165,9 @@ public: void SetStopID (uint32_t stop_id); - Mutex & + std::recursive_mutex & GetMutex() override; - + void Update (ThreadList &rhs); @@ -147,6 +185,7 @@ protected: Process *m_process; ///< The process that manages this thread list. uint32_t m_stop_id; ///< The process stop ID that this thread list is valid for. lldb::tid_t m_selected_tid; ///< For targets that need the notion of a current thread. + std::vector<lldb::tid_t> m_expression_tid_stack; private: diff --git a/include/lldb/Target/ThreadPlan.h b/include/lldb/Target/ThreadPlan.h index e6f9aeb78dd6..6dac4a299e52 100644 --- a/include/lldb/Target/ThreadPlan.h +++ b/include/lldb/Target/ThreadPlan.h @@ -12,13 +12,13 @@ // C Includes // C++ Includes +#include <mutex> #include <string> // Other libraries and framework includes // Project includes #include "lldb/lldb-private.h" #include "lldb/Core/UserID.h" -#include "lldb/Host/Mutex.h" #include "lldb/Target/Process.h" #include "lldb/Target/Target.h" #include "lldb/Target/Thread.h" @@ -632,7 +632,7 @@ private: ThreadPlanKind m_kind; std::string m_name; - Mutex m_plan_complete_mutex; + std::recursive_mutex m_plan_complete_mutex; LazyBool m_cached_plan_explains_stop; bool m_plan_complete; bool m_plan_private; diff --git a/include/lldb/Target/ThreadPlanPython.h b/include/lldb/Target/ThreadPlanPython.h index ab3fbbdf6fb5..8d5b217226f1 100644 --- a/include/lldb/Target/ThreadPlanPython.h +++ b/include/lldb/Target/ThreadPlanPython.h @@ -19,7 +19,6 @@ #include "lldb/lldb-private.h" #include "lldb/Core/StructuredData.h" #include "lldb/Core/UserID.h" -#include "lldb/Host/Mutex.h" #include "lldb/Target/Process.h" #include "lldb/Target/Target.h" #include "lldb/Target/Thread.h" diff --git a/include/lldb/Target/ThreadPlanStepInstruction.h b/include/lldb/Target/ThreadPlanStepInstruction.h index da83ecadcae6..27b9bf1133fe 100644 --- a/include/lldb/Target/ThreadPlanStepInstruction.h +++ b/include/lldb/Target/ThreadPlanStepInstruction.h @@ -23,6 +23,12 @@ namespace lldb_private { class ThreadPlanStepInstruction : public ThreadPlan { public: + ThreadPlanStepInstruction (Thread &thread, + bool step_over, + bool stop_others, + Vote stop_vote, + Vote run_vote); + ~ThreadPlanStepInstruction() override; void GetDescription(Stream *s, lldb::DescriptionLevel level) override; @@ -37,11 +43,6 @@ public: protected: bool DoPlanExplainsStop(Event *event_ptr) override; - ThreadPlanStepInstruction (Thread &thread, - bool step_over, - bool stop_others, - Vote stop_vote, - Vote run_vote); void SetUpState (); private: diff --git a/include/lldb/Target/Unwind.h b/include/lldb/Target/Unwind.h index 17c6c0df8207..09ba87a42bbe 100644 --- a/include/lldb/Target/Unwind.h +++ b/include/lldb/Target/Unwind.h @@ -12,10 +12,11 @@ // C Includes // C++ Includes +#include <mutex> + // Other libraries and framework includes // Project includes #include "lldb/lldb-private.h" -#include "lldb/Host/Mutex.h" namespace lldb_private { @@ -25,11 +26,7 @@ protected: //------------------------------------------------------------------ // Classes that inherit from Unwind can see and modify these //------------------------------------------------------------------ - Unwind(Thread &thread) : - m_thread (thread), - m_unwind_mutex(Mutex::eMutexTypeRecursive) - { - } + Unwind(Thread &thread) : m_thread(thread), m_unwind_mutex() {} public: virtual @@ -40,18 +37,17 @@ public: void Clear() { - Mutex::Locker locker(m_unwind_mutex); + std::lock_guard<std::recursive_mutex> guard(m_unwind_mutex); DoClear(); - } uint32_t GetFrameCount() { - Mutex::Locker locker(m_unwind_mutex); + std::lock_guard<std::recursive_mutex> guard(m_unwind_mutex); return DoGetFrameCount(); } - + uint32_t GetFramesUpTo (uint32_t end_idx) { @@ -70,21 +66,19 @@ public: } bool - GetFrameInfoAtIndex (uint32_t frame_idx, - lldb::addr_t& cfa, - lldb::addr_t& pc) + GetFrameInfoAtIndex(uint32_t frame_idx, lldb::addr_t &cfa, lldb::addr_t &pc) { - Mutex::Locker locker(m_unwind_mutex); - return DoGetFrameInfoAtIndex (frame_idx, cfa, pc); + std::lock_guard<std::recursive_mutex> guard(m_unwind_mutex); + return DoGetFrameInfoAtIndex(frame_idx, cfa, pc); } - + lldb::RegisterContextSP - CreateRegisterContextForFrame (StackFrame *frame) + CreateRegisterContextForFrame(StackFrame *frame) { - Mutex::Locker locker(m_unwind_mutex); - return DoCreateRegisterContextForFrame (frame); + std::lock_guard<std::recursive_mutex> guard(m_unwind_mutex); + return DoCreateRegisterContextForFrame(frame); } - + Thread & GetThread() { @@ -110,7 +104,8 @@ protected: DoCreateRegisterContextForFrame (StackFrame *frame) = 0; Thread &m_thread; - Mutex m_unwind_mutex; + std::recursive_mutex m_unwind_mutex; + private: DISALLOW_COPY_AND_ASSIGN (Unwind); }; diff --git a/include/lldb/Utility/Iterable.h b/include/lldb/Utility/Iterable.h index 2317225d126f..0c16a251b7a7 100644 --- a/include/lldb/Utility/Iterable.h +++ b/include/lldb/Utility/Iterable.h @@ -16,7 +16,6 @@ // Other libraries and framework includes // Project includes -#include "lldb/Host/Mutex.h" namespace lldb_private { @@ -207,36 +206,33 @@ public: return AdaptedConstIterator<C, E, A>(m_container.end()); } }; - -template <typename C, typename E, E (*A)(typename C::const_iterator &)> class LockingAdaptedIterable : public AdaptedIterable<C, E, A> + +template <typename C, typename E, E (*A)(typename C::const_iterator &), typename MutexType> +class LockingAdaptedIterable : public AdaptedIterable<C, E, A> { public: - LockingAdaptedIterable (C &container, Mutex &mutex) : - AdaptedIterable<C,E,A>(container), - m_mutex(&mutex) + LockingAdaptedIterable(C &container, MutexType &mutex) : AdaptedIterable<C, E, A>(container), m_mutex(&mutex) { - m_mutex->Lock(); + m_mutex->lock(); } - - LockingAdaptedIterable (LockingAdaptedIterable &&rhs) : - AdaptedIterable<C,E,A>(rhs), - m_mutex(rhs.m_mutex) + + LockingAdaptedIterable(LockingAdaptedIterable &&rhs) : AdaptedIterable<C, E, A>(rhs), m_mutex(rhs.m_mutex) { rhs.m_mutex = nullptr; } - - ~LockingAdaptedIterable () + + ~LockingAdaptedIterable() { if (m_mutex) - m_mutex->Unlock(); + m_mutex->unlock(); } - + private: - Mutex *m_mutex = nullptr; + MutexType *m_mutex = nullptr; DISALLOW_COPY_AND_ASSIGN(LockingAdaptedIterable); }; - + } // namespace lldb_private #endif // liblldb_Iterable_h_ diff --git a/include/lldb/Utility/ProcessStructReader.h b/include/lldb/Utility/ProcessStructReader.h index 80f90feb87ab..bbb497cd51cb 100644 --- a/include/lldb/Utility/ProcessStructReader.h +++ b/include/lldb/Utility/ProcessStructReader.h @@ -94,6 +94,15 @@ namespace lldb_private { return fail_value; return (RetType)(m_data.GetMaxU64(&offset, size)); } + + size_t + GetOffsetOf(ConstString name, size_t fail_value = SIZE_MAX) + { + auto iter = m_fields.find(name), end = m_fields.end(); + if (iter == end) + return fail_value; + return iter->second.offset; + } }; } diff --git a/include/lldb/Utility/SharedCluster.h b/include/lldb/Utility/SharedCluster.h index 2c03c409d97e..dfcc119e14bf 100644 --- a/include/lldb/Utility/SharedCluster.h +++ b/include/lldb/Utility/SharedCluster.h @@ -10,8 +10,8 @@ #ifndef utility_SharedCluster_h_ #define utility_SharedCluster_h_ +#include "lldb/Utility/LLDBAssert.h" #include "lldb/Utility/SharingPtr.h" -#include "lldb/Host/Mutex.h" #include "llvm/ADT/SmallPtrSet.h" @@ -46,14 +46,12 @@ template <class T> class ClusterManager { public: - ClusterManager () : - m_objects(), - m_external_ref(0), - m_mutex(Mutex::eMutexTypeNormal) {} - - ~ClusterManager () + ClusterManager() : m_objects(), m_external_ref(0), m_mutex() {} + + ~ClusterManager() { - for (typename llvm::SmallPtrSet<T *, 16>::iterator pos = m_objects.begin(), end = m_objects.end(); pos != end; ++pos) + for (typename llvm::SmallPtrSet<T *, 16>::iterator pos = m_objects.begin(), end = m_objects.end(); pos != end; + ++pos) { T *object = *pos; delete object; @@ -62,42 +60,48 @@ public: // Decrement refcount should have been called on this ClusterManager, // and it should have locked the mutex, now we will unlock it before // we destroy it... - m_mutex.Unlock(); + m_mutex.unlock(); } - - void ManageObject (T *new_object) + + void + ManageObject(T *new_object) { - Mutex::Locker locker (m_mutex); - m_objects.insert (new_object); + std::lock_guard<std::mutex> guard(m_mutex); + m_objects.insert(new_object); } - - typename lldb_private::SharingPtr<T> GetSharedPointer(T *desired_object) + + typename lldb_private::SharingPtr<T> + GetSharedPointer(T *desired_object) { { - Mutex::Locker locker (m_mutex); + std::lock_guard<std::mutex> guard(m_mutex); m_external_ref++; - assert (m_objects.count(desired_object)); + if (0 == m_objects.count(desired_object)) + { + lldbassert(false && "object not found in shared cluster when expected"); + desired_object = nullptr; + } } - return typename lldb_private::SharingPtr<T> (desired_object, new imp::shared_ptr_refcount<ClusterManager> (this)); + return typename lldb_private::SharingPtr<T>(desired_object, new imp::shared_ptr_refcount<ClusterManager>(this)); } - + private: - - void DecrementRefCount () + void + DecrementRefCount() { - m_mutex.Lock(); + m_mutex.lock(); m_external_ref--; if (m_external_ref == 0) delete this; else - m_mutex.Unlock(); + m_mutex.unlock(); } - + friend class imp::shared_ptr_refcount<ClusterManager>; - + llvm::SmallPtrSet<T *, 16> m_objects; int m_external_ref; - Mutex m_mutex; + std::mutex m_mutex; }; } // namespace lldb_private diff --git a/include/lldb/lldb-enumerations.h b/include/lldb/lldb-enumerations.h index ea31752b09be..d8f076f00b0e 100644 --- a/include/lldb/lldb-enumerations.h +++ b/include/lldb/lldb-enumerations.h @@ -271,17 +271,17 @@ namespace lldb { eErrorTypeWin32 ///< Standard Win32 error codes. }; - enum ValueType { - eValueTypeInvalid = 0, - eValueTypeVariableGlobal = 1, // globals variable - eValueTypeVariableStatic = 2, // static variable - eValueTypeVariableArgument = 3, // function argument variables - eValueTypeVariableLocal = 4, // function local variables - eValueTypeRegister = 5, // stack frame register value - eValueTypeRegisterSet = 6, // A collection of stack frame register values - eValueTypeConstResult = 7 // constant result variables + eValueTypeInvalid = 0, + eValueTypeVariableGlobal = 1, // globals variable + eValueTypeVariableStatic = 2, // static variable + eValueTypeVariableArgument = 3, // function argument variables + eValueTypeVariableLocal = 4, // function local variables + eValueTypeRegister = 5, // stack frame register value + eValueTypeRegisterSet = 6, // A collection of stack frame register values + eValueTypeConstResult = 7, // constant result variables + eValueTypeVariableThreadLocal = 8 // thread local storage variable }; //---------------------------------------------------------------------- @@ -378,7 +378,7 @@ namespace lldb { /// /// These enumerations use the same language enumerations as the DWARF /// specification for ease of use and consistency. - /// The enum -> string code is in LanguageRuntime.cpp, don't change this + /// The enum -> string code is in Language.cpp, don't change this /// table without updating that code as well. //---------------------------------------------------------------------- enum LanguageType @@ -434,6 +434,7 @@ namespace lldb { enum InstrumentationRuntimeType { eInstrumentationRuntimeTypeAddressSanitizer = 0x0000, + eInstrumentationRuntimeTypeThreadSanitizer = 0x0001, eNumInstrumentationRuntimeTypes }; @@ -453,7 +454,7 @@ namespace lldb { eAccessPackage }; - enum CommandArgumentType + enum CommandArgumentType { eArgTypeAddress = 0, eArgTypeAddressOrExpression, @@ -538,7 +539,8 @@ namespace lldb { eArgTypeWatchpointID, eArgTypeWatchpointIDRange, eArgTypeWatchType, - eArgTypeLastArg // Always keep this entry as the last entry in this enumeration!! + eArgRawInput, + eArgTypeLastArg // Always keep this entry as the last entry in this enumeration!! }; //---------------------------------------------------------------------- @@ -622,6 +624,7 @@ namespace lldb { eSectionTypeARMextab, eSectionTypeCompactUnwind, // compact unwind section in Mach-O, __TEXT,__unwind_info eSectionTypeGoSymtab, + eSectionTypeAbsoluteAddress, // Dummy section for symbols with absolute address eSectionTypeOther }; diff --git a/include/lldb/lldb-forward.h b/include/lldb/lldb-forward.h index 516f31911c2b..cb7979370849 100644 --- a/include/lldb/lldb-forward.h +++ b/include/lldb/lldb-forward.h @@ -59,6 +59,7 @@ class ClangPersistentVariables; class CommandInterpreter; class CommandInterpreterRunOptions; class CommandObject; +class CommandObjectMultiword; class CommandReturnObject; class Communication; class CompactUnwindInfo; @@ -79,6 +80,7 @@ class DataEncoder; class DataExtractor; class Debugger; class Declaration; +class DiagnosticManager; class Disassembler; class DumpValueObjectOptions; class DynamicCheckerFunctions; @@ -310,6 +312,8 @@ namespace lldb { typedef std::weak_ptr<lldb_private::BreakpointLocation> BreakpointLocationWP; typedef std::shared_ptr<lldb_private::BreakpointResolver> BreakpointResolverSP; typedef std::shared_ptr<lldb_private::Broadcaster> BroadcasterSP; + typedef std::shared_ptr<lldb_private::BroadcasterManager> BroadcasterManagerSP; + typedef std::weak_ptr<lldb_private::BroadcasterManager> BroadcasterManagerWP; typedef std::unique_ptr<lldb_private::ClangASTContext> ClangASTContextUP; typedef std::shared_ptr<lldb_private::ClangASTImporter> ClangASTImporterSP; typedef std::unique_ptr<lldb_private::ClangModulesDeclVendor> ClangModulesDeclVendorUP; @@ -328,6 +332,7 @@ namespace lldb { typedef std::shared_ptr<lldb_private::DynamicLoader> DynamicLoaderSP; typedef std::unique_ptr<lldb_private::DynamicLoader> DynamicLoaderUP; typedef std::shared_ptr<lldb_private::Event> EventSP; + typedef std::shared_ptr<lldb_private::EventData> EventDataSP; typedef std::shared_ptr<lldb_private::ExecutionContextRef> ExecutionContextRefSP; typedef std::shared_ptr<lldb_private::ExpressionVariable> ExpressionVariableSP; typedef std::shared_ptr<lldb_private::File> FileSP; @@ -348,8 +353,11 @@ namespace lldb { typedef std::unique_ptr<lldb_private::SystemRuntime> SystemRuntimeUP; typedef std::shared_ptr<lldb_private::LineTable> LineTableSP; typedef std::shared_ptr<lldb_private::Listener> ListenerSP; + typedef std::weak_ptr<lldb_private::Listener> ListenerWP; typedef std::shared_ptr<lldb_private::LogChannel> LogChannelSP; typedef std::shared_ptr<lldb_private::MemoryHistory> MemoryHistorySP; + typedef std::shared_ptr<lldb_private::MemoryRegionInfo> MemoryRegionInfoSP; + typedef std::unique_ptr<lldb_private::MemoryRegionInfo> MemoryRegionInfoUP; typedef std::shared_ptr<lldb_private::Module> ModuleSP; typedef std::weak_ptr<lldb_private::Module> ModuleWP; typedef std::shared_ptr<lldb_private::ObjectFile> ObjectFileSP; diff --git a/include/lldb/lldb-private-defines.h b/include/lldb/lldb-private-defines.h new file mode 100644 index 000000000000..4b261ad4712b --- /dev/null +++ b/include/lldb/lldb-private-defines.h @@ -0,0 +1,39 @@ +//===-- lldb-private-defines.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_lldb_private_defines_h_ +#define liblldb_lldb_private_defines_h_ + +#if defined(__cplusplus) + +// Include Compiler.h here so we don't define LLVM_FALLTHROUGH and then Compiler.h +// later tries to redefine it. +#include "llvm/Support/Compiler.h" + +#ifndef LLVM_FALLTHROUGH + +#ifndef __has_cpp_attribute +# define __has_cpp_attribute(x) 0 +#endif + +/// \macro LLVM_FALLTHROUGH +/// \brief Marks an empty statement preceding a deliberate switch fallthrough. +#if __has_cpp_attribute(clang::fallthrough) +#define LLVM_FALLTHROUGH [[clang::fallthrough]] +#else +#define LLVM_FALLTHROUGH +#endif + +#endif // ifndef LLVM_FALLTHROUGH + + + +#endif // #if defined(__cplusplus) + +#endif // liblldb_lldb_private_defines_h_ diff --git a/include/lldb/lldb-private-enumerations.h b/include/lldb/lldb-private-enumerations.h index 5f8f96c6da46..366970a39f2f 100644 --- a/include/lldb/lldb-private-enumerations.h +++ b/include/lldb/lldb-private-enumerations.h @@ -164,11 +164,12 @@ typedef enum FormatCategoryItem //------------------------------------------------------------------ /// Expression execution policies -//------------------------------------------------------------------ +//------------------------------------------------------------------ typedef enum { eExecutionPolicyOnlyWhenNeeded, eExecutionPolicyNever, - eExecutionPolicyAlways + eExecutionPolicyAlways, + eExecutionPolicyTopLevel // used for top-level code } ExecutionPolicy; //---------------------------------------------------------------------- diff --git a/include/lldb/lldb-private-interfaces.h b/include/lldb/lldb-private-interfaces.h index 6bc8dadaebff..8775ce6bc565 100644 --- a/include/lldb/lldb-private-interfaces.h +++ b/include/lldb/lldb-private-interfaces.h @@ -35,7 +35,7 @@ namespace lldb_private typedef lldb::CommandObjectSP (*LanguageRuntimeGetCommandObject) (CommandInterpreter& interpreter); typedef SystemRuntime *(*SystemRuntimeCreateInstance) (Process *process); typedef lldb::PlatformSP (*PlatformCreateInstance) (bool force, const ArchSpec *arch); - typedef lldb::ProcessSP (*ProcessCreateInstance) (lldb::TargetSP target_sp, Listener &listener, const FileSpec *crash_file_path); + typedef lldb::ProcessSP (*ProcessCreateInstance) (lldb::TargetSP target_sp, lldb::ListenerSP listener_sp, const FileSpec *crash_file_path); typedef lldb::ScriptInterpreterSP (*ScriptInterpreterCreateInstance)(CommandInterpreter &interpreter); typedef SymbolFile* (*SymbolFileCreateInstance) (ObjectFile* obj_file); typedef SymbolVendor* (*SymbolVendorCreateInstance) (const lldb::ModuleSP &module_sp, lldb_private::Stream *feedback_strm); // Module can be NULL for default system symbol vendor diff --git a/include/lldb/lldb-private-types.h b/include/lldb/lldb-private-types.h index 685034a1fee3..bdcf532b4305 100644 --- a/include/lldb/lldb-private-types.h +++ b/include/lldb/lldb-private-types.h @@ -103,6 +103,7 @@ namespace lldb_private }; typedef struct type128 { uint64_t x[2]; } type128; + typedef struct type256 { uint64_t x[4]; } type256; } // namespace lldb_private diff --git a/include/lldb/lldb-private.h b/include/lldb/lldb-private.h index 951b22fc94c5..cd6f1470e81d 100644 --- a/include/lldb/lldb-private.h +++ b/include/lldb/lldb-private.h @@ -24,6 +24,7 @@ #include "lldb/lldb-private-enumerations.h" #include "lldb/lldb-private-interfaces.h" #include "lldb/lldb-private-types.h" +#include "lldb/lldb-private-defines.h" namespace lldb_private { |