Update lldb to release_39 branch r276489 and resolve immediate conflicts.

This commit is contained in:
Ed Maste 2016-08-17 08:51:41 +00:00
commit 4bb0738ee7
662 changed files with 38535 additions and 22037 deletions

View File

@ -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"

View File

@ -83,13 +83,21 @@ class LLDB_API SBCommandReturnObject
bool
GetDescription (lldb::SBStream &description);
// deprecated, these two functions do not take
// ownership of file handle
void
SetImmediateOutputFile (FILE *fh);
void
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);

View File

@ -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;

View File

@ -110,6 +110,19 @@ class LLDB_API SBExpressionOptions
void
SetPrefix (const char *prefix);
void
SetAutoApplyFixIts(bool b = true);
bool
GetAutoApplyFixIts();
bool
GetTopLevel ();
void
SetTopLevel (bool b = true);
protected:

View File

@ -60,6 +60,9 @@ class LLDB_API SBFileSpec
bool
GetDescription (lldb::SBStream &description) const;
void
AppendPathComponent (const char *file_or_directory);
private:
friend class SBAttachInfo;
friend class SBBlock;

View File

@ -28,6 +28,9 @@ class LLDB_API SBHostOS
static lldb::SBFileSpec
GetLLDBPath (lldb::PathType path_type);
static lldb::SBFileSpec
GetUserHomeDirectory ();
static void
ThreadCreated (const char *name);

View File

@ -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 @@ class LLDB_API SBInstruction
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;
};

View File

@ -145,7 +145,7 @@ class LLDB_API SBLaunchInfo
GetShellExpandArguments ();
void
SetShellExpandArguments (bool glob);
SetShellExpandArguments (bool expand);
uint32_t
GetResumeCount ();

View File

@ -106,8 +106,6 @@ class LLDB_API SBListener
friend class SBLaunchInfo;
friend class SBTarget;
SBListener (lldb_private::Listener &listener);
SBListener (const lldb::ListenerSP &listener_sp);
lldb::ListenerSP
@ -124,20 +122,11 @@ class LLDB_API SBListener
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

View File

@ -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_

View File

@ -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 &region_info);
void
Append (lldb::SBMemoryRegionInfo &region);
void
Append (lldb::SBMemoryRegionInfoList &region_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_

View File

@ -393,6 +393,34 @@ class LLDB_API SBProcess
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 &region_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;

View File

@ -76,6 +76,7 @@ class LLDB_API SBStream
friend class SBInstruction;
friend class SBInstructionList;
friend class SBLineEntry;
friend class SBMemoryRegionInfo;
friend class SBModule;
friend class SBModuleSpec;
friend class SBModuleSpecList;

View File

@ -45,6 +45,9 @@ class LLDB_API SBStringList
const char *
GetStringAtIndex (size_t idx);
const char *
GetStringAtIndex (size_t idx) const;
void
Clear ();

View File

@ -620,6 +620,9 @@ class LLDB_API SBTarget
lldb::SBBreakpoint
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);
@ -657,6 +660,15 @@ class LLDB_API SBTarget
const SBFileSpecList &module_list,
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);
@ -681,6 +693,12 @@ class LLDB_API SBTarget
const SBFileSpecList &module_list,
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,

View File

@ -82,6 +82,9 @@ class LLDB_API SBThread
bool
GetStopReasonExtendedInfoAsJSON (lldb::SBStream &stream);
SBThreadCollection
GetStopReasonExtendedBacktraces (InstrumentationRuntimeType type);
size_t
GetStopDescription (char *dst, size_t dst_len);
@ -115,6 +118,12 @@ class LLDB_API SBThread
void
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 ();
@ -141,6 +150,9 @@ class LLDB_API SBThread
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()

View File

@ -58,6 +58,7 @@ class LLDB_API SBThreadCollection
private:
friend class SBProcess;
friend class SBThread;
lldb::ThreadCollectionSP m_opaque_sp;
};

View File

@ -125,6 +125,12 @@ class LLDB_API SBValue
bool
IsSynthetic ();
bool
IsSyntheticChildrenGenerated ();
void
SetSyntheticChildrenGenerated (bool);
const char *
GetLocation ();

View File

@ -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 @@ class BreakpointList
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 @@ class BreakpointList
/// 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 @@ class BreakpointList
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()
{

View File

@ -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 @@ class BreakpointLocation :
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

View File

@ -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 @@ class BreakpointLocationCollection
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;

View File

@ -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 @@ friend class Breakpoint;
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;

View File

@ -60,7 +60,7 @@ friend class Breakpoint;
/// @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
@ -77,6 +77,29 @@ friend class Breakpoint;
void
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 @@ friend class Breakpoint;
/// 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)

View File

@ -31,6 +31,7 @@ class BreakpointResolverFileLine :
BreakpointResolverFileLine (Breakpoint *bkpt,
const FileSpec &resolver,
uint32_t line_no,
lldb::addr_t m_offset,
bool check_inlines,
bool skip_prologue,
bool exact_match);

View File

@ -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 &regex,
const std::unordered_set<std::string> &func_name_set,
bool exact_match);
~BreakpointResolverFileRegex() override;
@ -48,6 +51,9 @@ class BreakpointResolverFileRegex :
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 @@ class BreakpointResolverFileRegex :
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);

View File

@ -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 @@ class BreakpointResolverName:
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 @@ class BreakpointResolverName:
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 @@ class BreakpointResolverName:
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 @@ class BreakpointResolverName:
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;

View File

@ -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 @@ class BreakpointSite :
// 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();

View File

@ -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 @@ friend class Process;
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 @@ friend class Process;
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.
};

View File

@ -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 @@ friend class Target;
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 @@ friend class Target;
/// 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 @@ friend class Target;
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;
};

View File

@ -69,9 +69,33 @@ class ArchSpec
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 @@ class ArchSpec
eCore_ppc64_generic,
eCore_ppc64_ppc970_64,
eCore_s390x_generic,
eCore_sparc_generic,
eCore_sparc9_generic,
@ -280,6 +306,24 @@ class ArchSpec
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 @@ class ArchSpec
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
{

View File

@ -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 @@ class BroadcastEventSpec
}
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 @@ class BroadcasterManager
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 @@ class BroadcasterManager
{
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,7 +204,37 @@ class BroadcasterManager
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 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;
@ -202,7 +242,6 @@ class BroadcasterManager
private:
const Listener *m_listener;
};
};
@ -241,6 +280,8 @@ class BroadcasterManager
//----------------------------------------------------------------------
class Broadcaster
{
friend class Listener;
friend class Event;
public:
//------------------------------------------------------------------
/// Construct with a broadcaster with a name.
@ -249,7 +290,7 @@ class Broadcaster
/// 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 @@ class Broadcaster
///
//------------------------------------------------------------------
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 @@ class Broadcaster
/// 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 @@ class Broadcaster
/// 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 @@ class Broadcaster
/// 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 @@ class Broadcaster
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 @@ class Broadcaster
/// @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 @@ class Broadcaster
/// @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 @@ class Broadcaster
// 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_

View File

@ -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 @@ class Communication : public Broadcaster
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;

View File

@ -290,13 +290,38 @@ class ConstString
m_string = nullptr;
}
//------------------------------------------------------------------
/// 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 @@ class ConstString
/// @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.

View File

@ -763,8 +763,10 @@ class DataExtractor
///
/// @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 @@ class DataExtractor
///
/// @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

View File

@ -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 @@ friend class SourceManager; // For GetSourceFileCache.
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 @@ friend class SourceManager; // For GetSourceFileCache.
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 @@ friend class SourceManager; // For GetSourceFileCache.
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 @@ friend class SourceManager; // For GetSourceFileCache.
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

View File

@ -384,6 +384,11 @@ class EmulateInstruction :
const RegisterInfo *reg_info,
const RegisterValue &reg_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 @@ class EmulateInstruction :
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;

View File

@ -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 @@ class EventDataBytes : public EventData
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 @@ class Event
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 @@ class Event
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 @@ class Event
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);

View File

@ -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 @@ class HistorySource
// 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 @@ class HistorySource
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);
};

View File

@ -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);
};

View File

@ -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 @@ class Listener
//------------------------------------------------------------------
// 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 @@ class Listener
}
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 @@ class Listener
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 @@ class Listener
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

View File

@ -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 |\

View File

@ -47,6 +47,9 @@ class MappedHash
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 @@ class MappedHash
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;

View File

@ -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 @@ class Module :
static Module *
GetAllocatedModuleAtIndex (size_t idx);
static Mutex *
static std::recursive_mutex &
GetAllocationModuleCollectionMutex();
//------------------------------------------------------------------
@ -498,6 +499,7 @@ class Module :
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 @@ class Module :
// 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 @@ class Module :
bool
RemapSourceFile (const char *path, std::string &new_path) const;
//------------------------------------------------------------------
/// Prepare to do a function name lookup.
//----------------------------------------------------------------------
/// @class LookupInfo Module.h "lldb/Core/Module.h"
/// @brief A class that encapsulates name lookup information.
///
/// 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".
/// 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.
///
/// @param[in] name
/// The user supplied name to use in the lookup
/// 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.
///
/// @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);
/// 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 @@ class Module :
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);

View File

@ -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 @@ class ModuleList
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 @@ class ModuleList
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 @@ class ModuleList
// 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()
{

View File

@ -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 @@ class ModuleSpec
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 @@ class ModuleSpecList
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 @@ class ModuleSpecList
}
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 @@ class ModuleSpecList
}
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 @@ class ModuleSpecList
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 @@ class ModuleSpecList
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 @@ class ModuleSpecList
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

View File

@ -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()
{

View File

@ -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;

View File

@ -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 @@ class Scalar
e_double,
e_long_double,
e_uint128,
e_sint128
e_sint128,
e_uint256,
e_sint256
};
//------------------------------------------------------------------
@ -91,6 +95,12 @@ class Scalar
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 @@ class Scalar
bool
ClearBit(uint32_t bit);
void *
const void *
GetBytes() const;
size_t
@ -152,6 +162,9 @@ class Scalar
bool
MakeSigned ();
bool
MakeUnsigned ();
static const char *
GetValueTypeAsCString (Scalar::Type value_type);
@ -221,9 +234,6 @@ class Scalar
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 @@ class Scalar
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 @@ class Scalar
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 @@ class Scalar
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);

View File

@ -94,7 +94,6 @@ class Searcher
class SearchFilter
{
public:
//------------------------------------------------------------------
/// The basic constructor takes a Target, which gives the space to search.
///
@ -108,7 +107,7 @@ class SearchFilter
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 @@ class SearchFilterByModule :
~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 @@ class SearchFilterByModuleList :
~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 @@ class SearchFilterByModuleListAndCU :
~SearchFilterByModuleListAndCU() override;
const SearchFilterByModuleListAndCU&
SearchFilterByModuleListAndCU&
operator=(const SearchFilterByModuleListAndCU& rhs);
bool

View File

@ -273,7 +273,19 @@ class Section :
{
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 @@ class Section :
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:

View File

@ -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 @@ class StreamCallback :
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);
};

View File

@ -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 @@ class StreamTee : public Stream
}
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 @@ class StreamTee : public Stream
// 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 @@ class StreamTee : public Stream
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 @@ class StreamTee : public Stream
}
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 @@ class StreamTee : public Stream
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;
};

View File

@ -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 @@ class ThreadSafeSTLMap
//------------------------------------------------------------------
// Constructors and Destructors
//------------------------------------------------------------------
ThreadSafeSTLMap() :
m_collection (),
m_mutex (Mutex::eMutexTypeRecursive)
{
}
ThreadSafeSTLMap() : m_collection(), m_mutex() {}
~ThreadSafeSTLMap()
{
@ -44,22 +40,22 @@ class ThreadSafeSTLMap
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 @@ class ThreadSafeSTLMap
}
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 @@ class ThreadSafeSTLMap
}
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 @@ class ThreadSafeSTLMap
}
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 @@ class ThreadSafeSTLMap
}
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 @@ class ThreadSafeSTLMap
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

View File

@ -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_

View File

@ -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 @@ class ThreadSafeValue
//------------------------------------------------------------------
// 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 @@ class ThreadSafeValue
}
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 @@ class ThreadSafeValue
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

View File

@ -50,9 +50,6 @@ class Timer
//--------------------------------------------------------------
~Timer();
static void
Initialize ();
void
Dump ();
@ -89,8 +86,6 @@ class Timer
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();

View File

@ -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 @@ class Properties
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;
};

View File

@ -169,9 +169,8 @@ class Value
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);
}
}

View File

@ -699,10 +699,16 @@ class ValueObject : public UserID
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 @@ class ValueObject : public UserID
return false;
}
bool
virtual bool
IsSyntheticChildrenGenerated ();
void
virtual void
SetSyntheticChildrenGenerated (bool b);
virtual SymbolContextScope *
@ -1028,35 +1034,32 @@ class ValueObject : public UserID
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 @@ class ValueObject : public UserID
{
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;
};

View File

@ -97,7 +97,10 @@ class ValueObjectConstResult : public ValueObject
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;

View File

@ -47,7 +47,8 @@ class ValueObjectConstResultCast : public ValueObjectCast
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;

View File

@ -53,7 +53,10 @@ class ValueObjectConstResultChild : public ValueObjectChild
}
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;

View File

@ -39,7 +39,10 @@ class ValueObjectConstResultImpl
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);

View File

@ -117,6 +117,12 @@ class ValueObjectDynamicValue : public ValueObject
void
SetPreferredDisplayLanguage (lldb::LanguageType);
bool
IsSyntheticChildrenGenerated () override;
void
SetSyntheticChildrenGenerated (bool b) override;
bool
GetDeclaration(Declaration &decl) override;

View File

@ -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 {
@ -146,6 +147,12 @@ class ValueObjectSynthetic : public ValueObject
void
SetPreferredDisplayLanguage (lldb::LanguageType);
bool
IsSyntheticChildrenGenerated () override;
void
SetSyntheticChildrenGenerated (bool b) override;
bool
GetDeclaration(Declaration &decl) override;
@ -177,6 +184,7 @@ class ValueObjectSynthetic : public ValueObject
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 @@ class ValueObjectSynthetic : public ValueObject
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;

View File

@ -152,6 +152,9 @@ class DumpValueObjectOptions
DumpValueObjectOptions&
SetRevealEmptyAggregates (bool reveal = true);
DumpValueObjectOptions&
SetElementCount (uint32_t element_count = 0);
public:
uint32_t m_max_depth = UINT32_MAX;
@ -163,6 +166,7 @@ class DumpValueObjectOptions
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;

View File

@ -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 @@ class FormatCache
};
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;

View File

@ -15,6 +15,7 @@
#include <atomic>
#include <initializer_list>
#include <map>
#include <mutex>
#include <vector>
// Other libraries and framework includes
@ -289,7 +290,7 @@ class FormatManager : public IFormatChangeListener
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;

View File

@ -15,6 +15,7 @@
#include <functional>
#include <map>
#include <memory>
#include <mutex>
#include <string>
// Other libraries and framework includes
@ -81,33 +82,27 @@ class FormatMap
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 @@ class FormatMap
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 @@ class FormatMap
}
}
}
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 @@ class FormatMap
}
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 @@ class FormatMap
}
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 @@ class FormattersContainer
}
bool
Delete_Impl (ConstString type, lldb::RegularExpressionSP *dummy)
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;
}
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 @@ class FormattersContainer
}
bool
Get_Impl (ConstString key, MapValueType& value, lldb::RegularExpressionSP *dummy)
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;
}
bool
GetExact_Impl (ConstString key, MapValueType& value, lldb::RegularExpressionSP *dummy)
{
Mutex& x_mutex = m_format_map.mutex();
lldb_private::Mutex::Locker locker(x_mutex);
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 (strcmp(regex->GetText(),key.AsCString()) == 0)
if (regex->Execute(key_cstr))
{
value = pos->second;
return true;
}
}
return false;
}
bool
GetExact_Impl(ConstString key, MapValueType &value, 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(regex->GetText(), key.AsCString()) == 0)
{
value = pos->second;
return true;

View File

@ -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);

View File

@ -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;

View File

@ -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;
};

View File

@ -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:

View File

@ -153,6 +153,10 @@ class ValueObjectPrinter
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);

View File

@ -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;

View File

@ -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 @@ class DWARFExpression
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 @@ class DWARFExpression
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 @@ class DWARFExpression
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 @@ class DWARFExpression
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);

View File

@ -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 */

View File

@ -57,16 +57,33 @@ class ExpressionParser
/// 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.

View File

@ -54,10 +54,17 @@ class ExpressionSourceCode
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,

View File

@ -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 @@ class PersistentExpressionState : public ExpressionVariableList {
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

View File

@ -99,17 +99,23 @@ class FunctionCaller : public Expression
//------------------------------------------------------------------
/// 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 @@ class FunctionCaller : public Expression
/// 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 @@ class FunctionCaller : public Expression
/// 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 @@ class FunctionCaller : public Expression
/// 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 @@ class FunctionCaller : public Expression
/// @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 @@ class FunctionCaller : public Expression
/// 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 @@ class FunctionCaller : public Expression
/// 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 @@ class FunctionCaller : public Expression
/// @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 @@ class FunctionCaller : public Expression
/// 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
///

View File

@ -61,8 +61,8 @@ class DynamicCheckerFunctions
/// 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 @@ class DynamicCheckerFunctions
/// 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;
};

View File

@ -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 @@ class IRExecutionUnit :
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 @@ class IRExecutionUnit :
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 @@ class IRExecutionUnit :
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 @@ class IRExecutionUnit :
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 @@ class IRExecutionUnit :
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 @@ class IRExecutionUnit :
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 @@ class IRExecutionUnit :
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

View File

@ -50,7 +50,7 @@ class IRInterpreter
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,

View File

@ -129,7 +129,7 @@ class IRMemoryMap
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);

View File

@ -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;
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,
Stream &error_stream) = 0;
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.

View File

@ -79,8 +79,8 @@ class UserExpression : public Expression
//------------------------------------------------------------------
/// 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 @@ class UserExpression : public Expression
/// 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 @@ class UserExpression : public Expression
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 @@ class UserExpression : public Expression
/// @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 @@ class UserExpression : public Expression
/// @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 @@ class UserExpression : public Expression
/// @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 @@ class UserExpression : public Expression
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 @@ class UserExpression : public Expression
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.

View File

@ -54,8 +54,8 @@ class UtilityFunction : public Expression
//------------------------------------------------------------------
/// 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 @@ class UtilityFunction : public Expression
/// 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 @@ class UtilityFunction : public Expression
}
// 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 *

View File

@ -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;
};
}

View File

@ -45,7 +45,7 @@ class File : public IOObject
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 @@ class File : public IOObject
{
}
File (const File &rhs);
//------------------------------------------------------------------
/// Constructor with path.
///
@ -138,9 +136,6 @@ class File : public IOObject
//------------------------------------------------------------------
~File() override;
File &
operator= (const File &rhs);
bool
IsValid() const override
{
@ -223,9 +218,9 @@ class File : public IOObject
Error
Close() override;
Error
Duplicate (const File &rhs);
void
Clear ();
int
GetDescriptor() const;
@ -554,6 +549,9 @@ class File : public IOObject
LazyBool m_is_interactive;
LazyBool m_is_real_terminal;
LazyBool m_supports_colors;
private:
DISALLOW_COPY_AND_ASSIGN(File);
};
} // namespace lldb_private

View File

@ -117,6 +117,12 @@ class FileSpec
//------------------------------------------------------------------
~FileSpec ();
bool
DirectoryEquals(const FileSpec &other) const;
bool
FileEquals(const FileSpec &other) const;
//------------------------------------------------------------------
/// Assignment operator.
///
@ -260,6 +266,19 @@ class FileSpec
static bool
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.
///

View File

@ -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);
};
}

View File

@ -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 @@ class Host
/// 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 @@ class Host
///
/// @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
{

View File

@ -34,6 +34,8 @@ class HostInfoBase
public:
static void Initialize();
static void
Terminate();
//------------------------------------------------------------------
/// Returns the number of CPUs on this current host.

View File

@ -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;
};

View File

@ -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;

View File

@ -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 @@ class OptionParser
eOptionalArgument
};
static void Prepare(Mutex::Locker &locker);
static void
Prepare(std::unique_lock<std::mutex> &lock);
static void EnableError(bool error);

View File

@ -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"
//----------------------------------------------------------------------

View File

@ -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;
};
}

View File

@ -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;

Some files were not shown because too many files have changed in this diff Show More