Update lldb to release_39 branch r276489 and resolve immediate conflicts.
This commit is contained in:
commit
4bb0738ee7
@ -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"
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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:
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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;
|
||||
};
|
||||
|
||||
|
||||
|
@ -145,7 +145,7 @@ class LLDB_API SBLaunchInfo
|
||||
GetShellExpandArguments ();
|
||||
|
||||
void
|
||||
SetShellExpandArguments (bool glob);
|
||||
SetShellExpandArguments (bool expand);
|
||||
|
||||
uint32_t
|
||||
GetResumeCount ();
|
||||
|
@ -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
|
||||
|
117
contrib/llvm/tools/lldb/include/lldb/API/SBMemoryRegionInfo.h
Normal file
117
contrib/llvm/tools/lldb/include/lldb/API/SBMemoryRegionInfo.h
Normal 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_
|
@ -0,0 +1,63 @@
|
||||
//===-- SBMemoryRegionInfoList.h --------------------------------*- C++ -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef LLDB_SBMemoryRegionInfoList_h_
|
||||
#define LLDB_SBMemoryRegionInfoList_h_
|
||||
|
||||
#include "lldb/API/SBDefines.h"
|
||||
|
||||
class MemoryRegionInfoListImpl;
|
||||
|
||||
namespace lldb {
|
||||
|
||||
class LLDB_API SBMemoryRegionInfoList
|
||||
{
|
||||
public:
|
||||
|
||||
SBMemoryRegionInfoList ();
|
||||
|
||||
SBMemoryRegionInfoList (const lldb::SBMemoryRegionInfoList &rhs);
|
||||
|
||||
const SBMemoryRegionInfoList &
|
||||
operator = (const SBMemoryRegionInfoList &rhs);
|
||||
|
||||
~SBMemoryRegionInfoList ();
|
||||
|
||||
uint32_t
|
||||
GetSize () const;
|
||||
|
||||
bool
|
||||
GetMemoryRegionAtIndex (uint32_t idx, SBMemoryRegionInfo ®ion_info);
|
||||
|
||||
void
|
||||
Append (lldb::SBMemoryRegionInfo ®ion);
|
||||
|
||||
void
|
||||
Append (lldb::SBMemoryRegionInfoList ®ion_list);
|
||||
|
||||
void
|
||||
Clear ();
|
||||
|
||||
protected:
|
||||
|
||||
const MemoryRegionInfoListImpl *
|
||||
operator->() const;
|
||||
|
||||
const MemoryRegionInfoListImpl &
|
||||
operator*() const;
|
||||
|
||||
private:
|
||||
|
||||
std::unique_ptr<MemoryRegionInfoListImpl> m_opaque_ap;
|
||||
|
||||
};
|
||||
|
||||
} // namespace lldb
|
||||
|
||||
#endif // LLDB_SBMemoryRegionInfoList_h_
|
@ -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 ®ion_info);
|
||||
|
||||
//------------------------------------------------------------------
|
||||
/// Return the list of memory regions within the process.
|
||||
///
|
||||
/// @return
|
||||
/// A list of all witin the process memory regions.
|
||||
//------------------------------------------------------------------
|
||||
lldb::SBMemoryRegionInfoList
|
||||
GetMemoryRegions();
|
||||
|
||||
protected:
|
||||
friend class SBAddress;
|
||||
friend class SBBreakpoint;
|
||||
|
@ -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;
|
||||
|
@ -45,6 +45,9 @@ class LLDB_API SBStringList
|
||||
const char *
|
||||
GetStringAtIndex (size_t idx);
|
||||
|
||||
const char *
|
||||
GetStringAtIndex (size_t idx) const;
|
||||
|
||||
void
|
||||
Clear ();
|
||||
|
||||
|
@ -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,
|
||||
|
@ -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()
|
||||
|
@ -58,6 +58,7 @@ class LLDB_API SBThreadCollection
|
||||
|
||||
private:
|
||||
friend class SBProcess;
|
||||
friend class SBThread;
|
||||
|
||||
lldb::ThreadCollectionSP m_opaque_sp;
|
||||
};
|
||||
|
@ -125,6 +125,12 @@ class LLDB_API SBValue
|
||||
|
||||
bool
|
||||
IsSynthetic ();
|
||||
|
||||
bool
|
||||
IsSyntheticChildrenGenerated ();
|
||||
|
||||
void
|
||||
SetSyntheticChildrenGenerated (bool);
|
||||
|
||||
const char *
|
||||
GetLocation ();
|
||||
|
@ -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()
|
||||
{
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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)
|
||||
|
@ -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);
|
||||
|
@ -12,9 +12,11 @@
|
||||
|
||||
// C Includes
|
||||
// C++ Includes
|
||||
#include <set>
|
||||
// Other libraries and framework includes
|
||||
// Project includes
|
||||
#include "lldb/Breakpoint/BreakpointResolver.h"
|
||||
#include "lldb/Core/ConstString.h"
|
||||
|
||||
namespace lldb_private {
|
||||
|
||||
@ -30,6 +32,7 @@ class BreakpointResolverFileRegex :
|
||||
public:
|
||||
BreakpointResolverFileRegex (Breakpoint *bkpt,
|
||||
RegularExpression ®ex,
|
||||
const std::unordered_set<std::string> &func_name_set,
|
||||
bool exact_match);
|
||||
|
||||
~BreakpointResolverFileRegex() override;
|
||||
@ -48,6 +51,9 @@ 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);
|
||||
|
@ -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;
|
||||
|
@ -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();
|
||||
|
@ -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.
|
||||
};
|
||||
|
||||
|
@ -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;
|
||||
};
|
||||
|
@ -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
|
||||
{
|
||||
|
@ -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_
|
||||
|
@ -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;
|
||||
|
@ -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.
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -384,6 +384,11 @@ class EmulateInstruction :
|
||||
const RegisterInfo *reg_info,
|
||||
const RegisterValue ®_value);
|
||||
|
||||
// Type to represent the condition of an instruction. The UINT32 value is reserved for the
|
||||
// unconditional case and all other value can be used in an architecture dependent way.
|
||||
typedef uint32_t InstructionCondition;
|
||||
static const InstructionCondition UnconditionalCondition = UINT32_MAX;
|
||||
|
||||
EmulateInstruction (const ArchSpec &arch);
|
||||
|
||||
~EmulateInstruction() override = default;
|
||||
@ -403,8 +408,8 @@ 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;
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
};
|
||||
|
||||
|
@ -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);
|
||||
};
|
||||
|
@ -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
|
||||
|
@ -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 |\
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
|
@ -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()
|
||||
{
|
||||
|
@ -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
|
||||
|
@ -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()
|
||||
{
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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
|
||||
|
@ -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:
|
||||
|
@ -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);
|
||||
};
|
||||
|
||||
|
@ -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;
|
||||
};
|
||||
|
||||
|
@ -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
|
||||
|
@ -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_
|
@ -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
|
||||
|
@ -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();
|
||||
|
@ -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;
|
||||
};
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
@ -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;
|
||||
};
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
};
|
||||
|
@ -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:
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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 */
|
@ -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.
|
||||
|
@ -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,
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
///
|
||||
|
@ -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;
|
||||
};
|
||||
|
@ -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
|
||||
|
@ -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,
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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.
|
||||
|
@ -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.
|
||||
|
@ -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 *
|
||||
|
@ -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;
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
|
@ -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.
|
||||
///
|
||||
|
@ -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);
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
{
|
||||
|
@ -34,6 +34,8 @@ class HostInfoBase
|
||||
|
||||
public:
|
||||
static void Initialize();
|
||||
static void
|
||||
Terminate();
|
||||
|
||||
//------------------------------------------------------------------
|
||||
/// Returns the number of CPUs on this current host.
|
||||
|
@ -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;
|
||||
};
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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"
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
|
@ -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;
|
||||
};
|
||||
}
|
||||
|
@ -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
Loading…
Reference in New Issue
Block a user