summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGreg Clayton <gclayton@apple.com>2015-06-25 21:46:34 +0000
committerGreg Clayton <gclayton@apple.com>2015-06-25 21:46:34 +0000
commitfd67de3a023958f7af064d27107906db621e5442 (patch)
tree0161c6deeafcdaff52c60581ba50584ed81a2f48
parent2474bfdebd2a61836dad20bd02f1e18ade01ba0e (diff)
Resubmitting 240466 after fixing the linux test suite failures.
A few extras were fixed - Symbol::GetAddress() now returns an Address object, not a reference. There were places where people were accessing the address of a symbol when the symbol's value wasn't an address symbol. On MacOSX, undefined symbols have a value zero and some places where using the symbol's address and getting an absolute address of zero (since an Address object with no section and an m_offset whose value isn't LLDB_INVALID_ADDRESS is considered an absolute address). So fixing this required some changes to make sure people were getting what they expected. - Since some places want to access the address as a reference, I added a few new functions to symbol: Address &Symbol::GetAddressRef(); const Address &Symbol::GetAddressRef() const; Linux test suite passes just fine now. <rdar://problem/21494354>
-rw-r--r--lldb/include/lldb/Core/RangeMap.h27
-rw-r--r--lldb/include/lldb/Core/StructuredData.h89
-rw-r--r--lldb/include/lldb/Symbol/Symbol.h68
-rw-r--r--lldb/include/lldb/Target/Memory.h17
-rw-r--r--lldb/source/API/SBSymbol.cpp9
-rw-r--r--lldb/source/API/SBThread.cpp4
-rw-r--r--lldb/source/Commands/CommandObjectSource.cpp4
-rw-r--r--lldb/source/Commands/CommandObjectTarget.cpp15
-rw-r--r--lldb/source/Core/Address.cpp6
-rw-r--r--lldb/source/Core/AddressResolverName.cpp4
-rw-r--r--lldb/source/Core/Disassembler.cpp2
-rw-r--r--lldb/source/Core/FormatEntity.cpp2
-rw-r--r--lldb/source/Core/Module.cpp5
-rw-r--r--lldb/source/Core/StructuredData.cpp4
-rw-r--r--lldb/source/Expression/ClangExpressionDeclMap.cpp125
-rw-r--r--lldb/source/Expression/IRExecutionUnit.cpp6
-rw-r--r--lldb/source/Expression/Materializer.cpp2
-rw-r--r--lldb/source/Plugins/DynamicLoader/Hexagon-DYLD/DynamicLoaderHexagonDYLD.cpp2
-rw-r--r--lldb/source/Plugins/DynamicLoader/Hexagon-DYLD/HexagonDYLDRendezvous.cpp2
-rw-r--r--lldb/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderMacOSXDYLD.cpp14
-rw-r--r--lldb/source/Plugins/InstrumentationRuntime/AddressSanitizer/AddressSanitizerRuntime.cpp4
-rw-r--r--lldb/source/Plugins/JITLoader/GDB/JITLoaderGDB.cpp6
-rw-r--r--lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV1.cpp4
-rw-r--r--lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV2.cpp8
-rw-r--r--lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCTrampolineHandler.cpp14
-rw-r--r--lldb/source/Plugins/LanguageRuntime/RenderScript/RenderScriptRuntime/RenderScriptRuntime.cpp8
-rw-r--r--lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp4
-rw-r--r--lldb/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp24
-rw-r--r--lldb/source/Plugins/ObjectFile/PECOFF/ObjectFilePECOFF.cpp4
-rw-r--r--lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp76
-rw-r--r--lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.h7
-rw-r--r--lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp636
-rw-r--r--lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h19
-rw-r--r--lldb/source/Plugins/Process/gdb-remote/ThreadGDBRemote.cpp7
-rw-r--r--lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp2
-rw-r--r--lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.cpp14
-rw-r--r--lldb/source/Plugins/SymbolFile/Symtab/SymbolFileSymtab.cpp2
-rw-r--r--lldb/source/Plugins/SystemRuntime/MacOSX/SystemRuntimeMacOSX.cpp6
-rw-r--r--lldb/source/Symbol/ObjectFile.cpp2
-rw-r--r--lldb/source/Symbol/Symbol.cpp25
-rw-r--r--lldb/source/Symbol/SymbolContext.cpp8
-rw-r--r--lldb/source/Symbol/Symtab.cpp8
-rw-r--r--lldb/source/Target/Memory.cpp139
-rw-r--r--lldb/source/Target/Process.cpp5
-rw-r--r--lldb/source/Target/ThreadPlanStepRange.cpp4
-rw-r--r--lldb/tools/debugserver/debugserver.xcodeproj/project.pbxproj2
-rw-r--r--lldb/tools/debugserver/source/RNBRemote.cpp199
-rw-r--r--lldb/tools/debugserver/source/RNBRemote.h2
48 files changed, 1176 insertions, 470 deletions
diff --git a/lldb/include/lldb/Core/RangeMap.h b/lldb/include/lldb/Core/RangeMap.h
index d78504c7d28..d2c43a5d794 100644
--- a/lldb/include/lldb/Core/RangeMap.h
+++ b/lldb/include/lldb/Core/RangeMap.h
@@ -128,9 +128,10 @@ namespace lldb_private {
{
return Contains(range.GetRangeBase()) && ContainsEndInclusive(range.GetRangeEnd());
}
-
+
+ // Returns true if the two ranges adjoing or intersect
bool
- Overlap (const Range &rhs) const
+ DoesAdjoinOrIntersect (const Range &rhs) const
{
const BaseType lhs_base = this->GetRangeBase();
const BaseType rhs_base = rhs.GetRangeBase();
@@ -139,7 +140,19 @@ namespace lldb_private {
bool result = (lhs_base <= rhs_end) && (lhs_end >= rhs_base);
return result;
}
-
+
+ // Returns true if the two ranges intersect
+ bool
+ DoesIntersect (const Range &rhs) const
+ {
+ const BaseType lhs_base = this->GetRangeBase();
+ const BaseType rhs_base = rhs.GetRangeBase();
+ const BaseType lhs_end = this->GetRangeEnd();
+ const BaseType rhs_end = rhs.GetRangeEnd();
+ bool result = (lhs_base < rhs_end) && (lhs_end > rhs_base);
+ return result;
+ }
+
bool
operator < (const Range &rhs) const
{
@@ -241,7 +254,7 @@ namespace lldb_private {
// don't end up allocating and making a new collection for no reason
for (pos = m_entries.begin(), end = m_entries.end(), prev = end; pos != end; prev = pos++)
{
- if (prev != end && prev->Overlap(*pos))
+ if (prev != end && prev->DoesAdjoinOrIntersect(*pos))
{
can_combine = true;
break;
@@ -255,7 +268,7 @@ namespace lldb_private {
Collection minimal_ranges;
for (pos = m_entries.begin(), end = m_entries.end(), prev = end; pos != end; prev = pos++)
{
- if (prev != end && prev->Overlap(*pos))
+ if (prev != end && prev->DoesAdjoinOrIntersect(*pos))
minimal_ranges.back().SetRangeEnd (std::max<BaseType>(prev->GetRangeEnd(), pos->GetRangeEnd()));
else
minimal_ranges.push_back (*pos);
@@ -521,7 +534,7 @@ namespace lldb_private {
// don't end up allocating and making a new collection for no reason
for (pos = m_entries.begin(), end = m_entries.end(), prev = end; pos != end; prev = pos++)
{
- if (prev != end && prev->Overlap(*pos))
+ if (prev != end && prev->DoesAdjoinOrIntersect(*pos))
{
can_combine = true;
break;
@@ -535,7 +548,7 @@ namespace lldb_private {
Collection minimal_ranges;
for (pos = m_entries.begin(), end = m_entries.end(), prev = end; pos != end; prev = pos++)
{
- if (prev != end && prev->Overlap(*pos))
+ if (prev != end && prev->DoesAdjoinOrIntersect(*pos))
minimal_ranges.back().SetRangeEnd (std::max<BaseType>(prev->GetRangeEnd(), pos->GetRangeEnd()));
else
minimal_ranges.push_back (*pos);
diff --git a/lldb/include/lldb/Core/StructuredData.h b/lldb/include/lldb/Core/StructuredData.h
index 9a54fb3429b..8acfa310dea 100644
--- a/lldb/include/lldb/Core/StructuredData.h
+++ b/lldb/include/lldb/Core/StructuredData.h
@@ -13,10 +13,11 @@
// C Includes
// C++ Includes
+#include <functional>
#include <map>
+#include <string>
#include <utility>
#include <vector>
-#include <string>
#include "llvm/ADT/StringRef.h"
@@ -140,6 +141,15 @@ public:
return NULL;
}
+ uint64_t
+ GetIntegerValue (uint64_t fail_value = 0)
+ {
+ Integer *integer = GetAsInteger ();
+ if (integer)
+ return integer->GetValue();
+ return fail_value;
+ }
+
Float *
GetAsFloat ()
{
@@ -148,6 +158,15 @@ public:
return NULL;
}
+ double
+ GetFloatValue (double fail_value = 0.0)
+ {
+ Float *f = GetAsFloat ();
+ if (f)
+ return f->GetValue();
+ return fail_value;
+ }
+
Boolean *
GetAsBoolean ()
{
@@ -156,6 +175,15 @@ public:
return NULL;
}
+ bool
+ GetBooleanValue (bool fail_value = false)
+ {
+ Boolean *b = GetAsBoolean ();
+ if (b)
+ return b->GetValue();
+ return fail_value;
+ }
+
String *
GetAsString ()
{
@@ -164,6 +192,19 @@ public:
return NULL;
}
+ std::string
+ GetStringValue(const char *fail_value = NULL)
+ {
+ String *s = GetAsString ();
+ if (s)
+ return s->GetValue();
+
+ if (fail_value && fail_value[0])
+ return std::string(fail_value);
+
+ return std::string();
+ }
+
Generic *
GetAsGeneric()
{
@@ -197,6 +238,17 @@ public:
{
}
+ void
+ ForEach (std::function <bool(Object* object)> const &foreach_callback) const
+ {
+ for (const auto &object_sp : m_items)
+ {
+ if (foreach_callback(object_sp.get()) == false)
+ break;
+ }
+ }
+
+
size_t
GetSize() const
{
@@ -447,7 +499,7 @@ public:
m_value = string;
}
- std::string
+ const std::string &
GetValue ()
{
return m_value;
@@ -462,6 +514,7 @@ public:
class Dictionary : public Object
{
public:
+
Dictionary () :
Object (Type::eTypeDictionary),
m_dict ()
@@ -478,6 +531,16 @@ public:
return m_dict.size();
}
+ void
+ ForEach (std::function <bool(ConstString key, Object* object)> const &callback) const
+ {
+ for (const auto &pair : m_dict)
+ {
+ if (callback (pair.first, pair.second.get()) == false)
+ break;
+ }
+ }
+
ObjectSP
GetKeys() const
{
@@ -628,33 +691,25 @@ public:
void
AddIntegerItem (llvm::StringRef key, uint64_t value)
{
- ObjectSP val_obj (new Integer());
- val_obj->GetAsInteger()->SetValue (value);
- AddItem (key, val_obj);
+ AddItem (key, ObjectSP (new Integer(value)));
}
void
AddFloatItem (llvm::StringRef key, double value)
{
- ObjectSP val_obj (new Float());
- val_obj->GetAsFloat()->SetValue (value);
- AddItem (key, val_obj);
+ AddItem (key, ObjectSP (new Float(value)));
}
void
AddStringItem (llvm::StringRef key, std::string value)
{
- ObjectSP val_obj (new String());
- val_obj->GetAsString()->SetValue (value);
- AddItem (key, val_obj);
+ AddItem (key, ObjectSP (new String(std::move(value))));
}
void
AddBooleanItem (llvm::StringRef key, bool value)
{
- ObjectSP val_obj (new Boolean());
- val_obj->GetAsBoolean()->SetValue (value);
- AddItem (key, val_obj);
+ AddItem (key, ObjectSP (new Boolean(value)));
}
void Dump(Stream &s) const override;
@@ -690,9 +745,9 @@ public:
class Generic : public Object
{
public:
- explicit Generic(void *object = nullptr)
- : Object(Type::eTypeGeneric)
- , m_object(object)
+ explicit Generic(void *object = nullptr) :
+ Object (Type::eTypeGeneric),
+ m_object (object)
{
}
diff --git a/lldb/include/lldb/Symbol/Symbol.h b/lldb/include/lldb/Symbol/Symbol.h
index 6e14dfff044..ad11563634e 100644
--- a/lldb/include/lldb/Symbol/Symbol.h
+++ b/lldb/include/lldb/Symbol/Symbol.h
@@ -72,25 +72,81 @@ public:
ValueIsAddress() const;
//------------------------------------------------------------------
- // Access the address value. Do NOT hand out the AddressRange as an
- // object as the byte size of the address range may not be filled in
- // and it should be accessed via GetByteSize().
+ // The GetAddressRef() accessor functions should only be called if
+ // you previously call ValueIsAddress() otherwise you might get an
+ // reference to an Address object that contains an constant integer
+ // value in m_addr_range.m_base_addr.m_offset which could be
+ // incorrectly used to represent an absolute address since it has
+ // no section.
//------------------------------------------------------------------
Address &
- GetAddress()
+ GetAddressRef()
{
return m_addr_range.GetBaseAddress();
}
+ const Address &
+ GetAddressRef() const
+ {
+ return m_addr_range.GetBaseAddress();
+ }
+
+ //------------------------------------------------------------------
+ // Makes sure the symbol's value is an address and returns the file
+ // address. Returns LLDB_INVALID_ADDRESS if the symbol's value isn't
+ // an address.
+ //------------------------------------------------------------------
+ lldb::addr_t
+ GetFileAddress () const;
+
+ //------------------------------------------------------------------
+ // Makes sure the symbol's value is an address and gets the load
+ // address using \a target if it is. Returns LLDB_INVALID_ADDRESS
+ // if the symbol's value isn't an address or if the section isn't
+ // loaded in \a target.
+ //------------------------------------------------------------------
+ lldb::addr_t
+ GetLoadAddress (Target *target) const;
+
//------------------------------------------------------------------
// Access the address value. Do NOT hand out the AddressRange as an
// object as the byte size of the address range may not be filled in
// and it should be accessed via GetByteSize().
//------------------------------------------------------------------
- const Address &
+ Address
GetAddress() const
{
- return m_addr_range.GetBaseAddress();
+ // Make sure the our value is an address before we hand a copy out.
+ // We use the Address inside m_addr_range to contain the value for
+ // symbols that are not address based symbols so we are using it
+ // for more than just addresses. For example undefined symbols on
+ // MacOSX have a nlist.n_value of 0 (zero) and this will get placed
+ // into m_addr_range.m_base_addr.m_offset and it will have no section.
+ // So in the GetAddress() accessor, we need to hand out an invalid
+ // address if the symbol's value isn't an address.
+ if (ValueIsAddress())
+ return m_addr_range.GetBaseAddress();
+ else
+ return Address();
+ }
+
+ // When a symbol's value isn't an address, we need to access the raw
+ // value. This function will ensure this symbol's value isn't an address
+ // and return the integer value if this checks out, otherwise it will
+ // return "fail_value" if the symbol is an address value.
+ uint64_t
+ GetIntegerValue (uint64_t fail_value = 0) const
+ {
+ if (ValueIsAddress())
+ {
+ // This symbol's value is an address. Use Symbol::GetAddress() to get the address.
+ return fail_value;
+ }
+ else
+ {
+ // The value is stored in the base address' offset
+ return m_addr_range.GetBaseAddress().GetOffset();
+ }
}
lldb::addr_t
diff --git a/lldb/include/lldb/Target/Memory.h b/lldb/include/lldb/Target/Memory.h
index 568bbcdf2f7..bf1cc187878 100644
--- a/lldb/include/lldb/Target/Memory.h
+++ b/lldb/include/lldb/Target/Memory.h
@@ -52,7 +52,7 @@ namespace lldb_private {
uint32_t
GetMemoryCacheLineSize() const
{
- return m_cache_line_byte_size ;
+ return m_L2_cache_line_byte_size ;
}
void
@@ -61,17 +61,26 @@ namespace lldb_private {
bool
RemoveInvalidRange (lldb::addr_t base_addr, lldb::addr_t byte_size);
+ // Allow external sources to populate data into the L1 memory cache
+ void
+ AddL1CacheData(lldb::addr_t addr, const void *src, size_t src_len);
+
+ void
+ AddL1CacheData(lldb::addr_t addr, const lldb::DataBufferSP &data_buffer_sp);
+
protected:
typedef std::map<lldb::addr_t, lldb::DataBufferSP> BlockMap;
typedef RangeArray<lldb::addr_t, lldb::addr_t, 4> InvalidRanges;
+ typedef Range<lldb::addr_t, lldb::addr_t> AddrRange;
//------------------------------------------------------------------
// Classes that inherit from MemoryCache can see and modify these
//------------------------------------------------------------------
- Process &m_process;
- uint32_t m_cache_line_byte_size;
Mutex m_mutex;
- BlockMap m_cache;
+ BlockMap m_L1_cache; // A first level memory cache whose chunk sizes vary that will be used only if the memory read fits entirely in a chunk
+ BlockMap m_L2_cache; // A memory cache of fixed size chinks (m_L2_cache_line_byte_size bytes in size each)
InvalidRanges m_invalid_ranges;
+ Process &m_process;
+ uint32_t m_L2_cache_line_byte_size;
private:
DISALLOW_COPY_AND_ASSIGN (MemoryCache);
};
diff --git a/lldb/source/API/SBSymbol.cpp b/lldb/source/API/SBSymbol.cpp
index 12a3b317d50..246a455d93a 100644
--- a/lldb/source/API/SBSymbol.cpp
+++ b/lldb/source/API/SBSymbol.cpp
@@ -137,10 +137,11 @@ SBSymbol::GetInstructions (SBTarget target, const char *flavor_string)
}
if (m_opaque_ptr->ValueIsAddress())
{
- ModuleSP module_sp (m_opaque_ptr->GetAddress().GetModule());
+ const Address &symbol_addr = m_opaque_ptr->GetAddressRef();
+ ModuleSP module_sp = symbol_addr.GetModule();
if (module_sp)
{
- AddressRange symbol_range (m_opaque_ptr->GetAddress(), m_opaque_ptr->GetByteSize());
+ AddressRange symbol_range (symbol_addr, m_opaque_ptr->GetByteSize());
const bool prefer_file_cache = false;
sb_instructions.SetDisassembler (Disassembler::DisassembleRange (module_sp->GetArchitecture (),
NULL,
@@ -172,7 +173,7 @@ SBSymbol::GetStartAddress ()
SBAddress addr;
if (m_opaque_ptr && m_opaque_ptr->ValueIsAddress())
{
- addr.SetAddress (&m_opaque_ptr->GetAddress());
+ addr.SetAddress (&m_opaque_ptr->GetAddressRef());
}
return addr;
}
@@ -186,7 +187,7 @@ SBSymbol::GetEndAddress ()
lldb::addr_t range_size = m_opaque_ptr->GetByteSize();
if (range_size > 0)
{
- addr.SetAddress (&m_opaque_ptr->GetAddress());
+ addr.SetAddress (&m_opaque_ptr->GetAddressRef());
addr->Slide (m_opaque_ptr->GetByteSize());
}
}
diff --git a/lldb/source/API/SBThread.cpp b/lldb/source/API/SBThread.cpp
index 78f57f52102..dfc7ce9629f 100644
--- a/lldb/source/API/SBThread.cpp
+++ b/lldb/source/API/SBThread.cpp
@@ -114,13 +114,13 @@ SBThread::GetQueue () const
else
{
if (log)
- log->Printf ("SBThread(%p)::GetQueueKind() => error: process is running",
+ log->Printf ("SBThread(%p)::GetQueue() => error: process is running",
static_cast<void*>(exe_ctx.GetThreadPtr()));
}
}
if (log)
- log->Printf ("SBThread(%p)::GetQueueKind () => SBQueue(%p)",
+ log->Printf ("SBThread(%p)::GetQueue () => SBQueue(%p)",
static_cast<void*>(exe_ctx.GetThreadPtr()), static_cast<void*>(queue_sp.get()));
return sb_queue;
diff --git a/lldb/source/Commands/CommandObjectSource.cpp b/lldb/source/Commands/CommandObjectSource.cpp
index e30aeca6025..7c5f127cb51 100644
--- a/lldb/source/Commands/CommandObjectSource.cpp
+++ b/lldb/source/Commands/CommandObjectSource.cpp
@@ -537,9 +537,9 @@ protected:
{
SymbolContext sc;
sc_list_symbols.GetContextAtIndex (i, sc);
- if (sc.symbol)
+ if (sc.symbol && sc.symbol->ValueIsAddress())
{
- const Address &base_address = sc.symbol->GetAddress();
+ const Address &base_address = sc.symbol->GetAddressRef();
Function *function = base_address.CalculateSymbolContextFunction();
if (function)
{
diff --git a/lldb/source/Commands/CommandObjectTarget.cpp b/lldb/source/Commands/CommandObjectTarget.cpp
index 864055d33d9..7257ff36f4f 100644
--- a/lldb/source/Commands/CommandObjectTarget.cpp
+++ b/lldb/source/Commands/CommandObjectTarget.cpp
@@ -1734,17 +1734,16 @@ LookupSymbolInModule (CommandInterpreter &interpreter, Stream &strm, Module *mod
DumpFullpath (strm, &module->GetFileSpec(), 0);
strm.PutCString(":\n");
strm.IndentMore ();
- //Symtab::DumpSymbolHeader (&strm);
for (i=0; i < num_matches; ++i)
{
Symbol *symbol = symtab->SymbolAtIndex(match_indexes[i]);
- DumpAddress (interpreter.GetExecutionContext().GetBestExecutionContextScope(),
- symbol->GetAddress(),
- verbose,
- strm);
-
-// strm.Indent ();
-// symbol->Dump (&strm, interpreter.GetExecutionContext().GetTargetPtr(), i);
+ if (symbol && symbol->ValueIsAddress())
+ {
+ DumpAddress (interpreter.GetExecutionContext().GetBestExecutionContextScope(),
+ symbol->GetAddressRef(),
+ verbose,
+ strm);
+ }
}
strm.IndentLess ();
return num_matches;
diff --git a/lldb/source/Core/Address.cpp b/lldb/source/Core/Address.cpp
index 6d4e2ff8982..1cd7a7447b7 100644
--- a/lldb/source/Core/Address.cpp
+++ b/lldb/source/Core/Address.cpp
@@ -501,7 +501,7 @@ Address::Dump (Stream *s, ExecutionContextScope *exe_scope, DumpStyle style, Dum
if (symbol_name)
{
s->PutCString(symbol_name);
- addr_t delta = file_Addr - symbol->GetAddress().GetFileAddress();
+ addr_t delta = file_Addr - symbol->GetAddressRef().GetFileAddress();
if (delta)
s->Printf(" + %" PRIu64, delta);
showed_info = true;
@@ -669,7 +669,7 @@ Address::Dump (Stream *s, ExecutionContextScope *exe_scope, DumpStyle style, Dum
// If we have just a symbol make sure it is in the right section
if (sc.symbol->ValueIsAddress())
{
- if (sc.symbol->GetAddress().GetSection() != GetSection())
+ if (sc.symbol->GetAddressRef().GetSection() != GetSection())
{
// don't show the module if the symbol is a trampoline symbol
show_stop_context = false;
@@ -722,7 +722,7 @@ Address::Dump (Stream *s, ExecutionContextScope *exe_scope, DumpStyle style, Dum
// as our address. If it isn't, then we might have just found
// the last symbol that came before the address that we are
// looking up that has nothing to do with our address lookup.
- if (sc.symbol->ValueIsAddress() && sc.symbol->GetAddress().GetSection() != GetSection())
+ if (sc.symbol->ValueIsAddress() && sc.symbol->GetAddressRef().GetSection() != GetSection())
sc.symbol = NULL;
}
sc.GetDescription(s, eDescriptionLevelBrief, target);
diff --git a/lldb/source/Core/AddressResolverName.cpp b/lldb/source/Core/AddressResolverName.cpp
index d47fa1ede4a..1c6205fa6bd 100644
--- a/lldb/source/Core/AddressResolverName.cpp
+++ b/lldb/source/Core/AddressResolverName.cpp
@@ -165,7 +165,7 @@ AddressResolverName::SearchCallback
{
if (symbol_sc.symbol && symbol_sc.symbol->ValueIsAddress())
{
- if (sc.function->GetAddressRange().GetBaseAddress() == symbol_sc.symbol->GetAddress())
+ if (sc.function->GetAddressRange().GetBaseAddress() == symbol_sc.symbol->GetAddressRef())
{
sym_list.RemoveContextAtIndex(j);
continue; // Don't increment j
@@ -211,7 +211,7 @@ AddressResolverName::SearchCallback
{
if (sc.symbol && sc.symbol->ValueIsAddress())
{
- func_addr = sc.symbol->GetAddress();
+ func_addr = sc.symbol->GetAddressRef();
addr_t byte_size = sc.symbol->GetByteSize();
if (skip_prologue)
diff --git a/lldb/source/Core/Disassembler.cpp b/lldb/source/Core/Disassembler.cpp
index edfc49bf36e..f96232fccee 100644
--- a/lldb/source/Core/Disassembler.cpp
+++ b/lldb/source/Core/Disassembler.cpp
@@ -548,7 +548,7 @@ Disassembler::Disassemble
}
else if (sc.symbol && sc.symbol->ValueIsAddress())
{
- range.GetBaseAddress() = sc.symbol->GetAddress();
+ range.GetBaseAddress() = sc.symbol->GetAddressRef();
range.SetByteSize (sc.symbol->GetByteSize());
}
else
diff --git a/lldb/source/Core/FormatEntity.cpp b/lldb/source/Core/FormatEntity.cpp
index 1dec0bfb97e..2ebe95747bc 100644
--- a/lldb/source/Core/FormatEntity.cpp
+++ b/lldb/source/Core/FormatEntity.cpp
@@ -477,7 +477,7 @@ DumpAddressOffsetFromFunction (Stream &s,
}
}
else if (sc->symbol && sc->symbol->ValueIsAddress())
- func_addr = sc->symbol->GetAddress();
+ func_addr = sc->symbol->GetAddressRef();
}
if (func_addr.IsValid())
diff --git a/lldb/source/Core/Module.cpp b/lldb/source/Core/Module.cpp
index 6696597834e..eb0359d02d5 100644
--- a/lldb/source/Core/Module.cpp
+++ b/lldb/source/Core/Module.cpp
@@ -902,10 +902,9 @@ Module::FindFunctions (const RegularExpression& regex,
{
sc.symbol = symtab->SymbolAtIndex(symbol_indexes[i]);
SymbolType sym_type = sc.symbol->GetType();
- if (sc.symbol && (sym_type == eSymbolTypeCode ||
- sym_type == eSymbolTypeResolver))
+ if (sc.symbol && sc.symbol->ValueIsAddress() && (sym_type == eSymbolTypeCode || sym_type == eSymbolTypeResolver))
{
- FileAddrToIndexMap::const_iterator pos = file_addr_to_index.find(sc.symbol->GetAddress().GetFileAddress());
+ FileAddrToIndexMap::const_iterator pos = file_addr_to_index.find(sc.symbol->GetAddressRef().GetFileAddress());
if (pos == end)
sc_list.Append(sc);
else
diff --git a/lldb/source/Core/StructuredData.cpp b/lldb/source/Core/StructuredData.cpp
index 9286c3a2991..a2c440948af 100644
--- a/lldb/source/Core/StructuredData.cpp
+++ b/lldb/source/Core/StructuredData.cpp
@@ -298,6 +298,10 @@ StructuredData::ParseJSON (std::string json_text)
{
object_sp = read_json_object (&c);
}
+ else if (*c == '[')
+ {
+ object_sp = read_json_array (&c);
+ }
else
{
// We have bad characters here, this is likely an illegal JSON string.
diff --git a/lldb/source/Expression/ClangExpressionDeclMap.cpp b/lldb/source/Expression/ClangExpressionDeclMap.cpp
index 42a7d769b89..1013bb54060 100644
--- a/lldb/source/Expression/ClangExpressionDeclMap.cpp
+++ b/lldb/source/Expression/ClangExpressionDeclMap.cpp
@@ -665,74 +665,71 @@ ClangExpressionDeclMap::GetSymbolAddress (Target &target,
SymbolContext sym_ctx;
sc_list.GetContextAtIndex(i, sym_ctx);
- const Address *sym_address = &sym_ctx.symbol->GetAddress();
+ const Address sym_address = sym_ctx.symbol->GetAddress();
- if (!sym_address || !sym_address->IsValid())
+ if (!sym_address.IsValid())
continue;
- if (sym_address)
+ switch (sym_ctx.symbol->GetType())
{
- switch (sym_ctx.symbol->GetType())
- {
- case eSymbolTypeCode:
- case eSymbolTypeTrampoline:
- symbol_load_addr = sym_address->GetCallableLoadAddress (&target);
- break;
+ case eSymbolTypeCode:
+ case eSymbolTypeTrampoline:
+ symbol_load_addr = sym_address.GetCallableLoadAddress (&target);
+ break;
- case eSymbolTypeResolver:
- symbol_load_addr = sym_address->GetCallableLoadAddress (&target, true);
- break;
+ case eSymbolTypeResolver:
+ symbol_load_addr = sym_address.GetCallableLoadAddress (&target, true);
+ break;
- case eSymbolTypeReExported:
+ case eSymbolTypeReExported:
+ {
+ ConstString reexport_name = sym_ctx.symbol->GetReExportedSymbolName();
+ if (reexport_name)
{
- ConstString reexport_name = sym_ctx.symbol->GetReExportedSymbolName();
- if (reexport_name)
+ ModuleSP reexport_module_sp;
+ ModuleSpec reexport_module_spec;
+ reexport_module_spec.GetPlatformFileSpec() = sym_ctx.symbol->GetReExportedSymbolSharedLibrary();
+ if (reexport_module_spec.GetPlatformFileSpec())
{
- ModuleSP reexport_module_sp;
- ModuleSpec reexport_module_spec;
- reexport_module_spec.GetPlatformFileSpec() = sym_ctx.symbol->GetReExportedSymbolSharedLibrary();
- if (reexport_module_spec.GetPlatformFileSpec())
+ reexport_module_sp = target.GetImages().FindFirstModule(reexport_module_spec);
+ if (!reexport_module_sp)
{
+ reexport_module_spec.GetPlatformFileSpec().GetDirectory().Clear();
reexport_module_sp = target.GetImages().FindFirstModule(reexport_module_spec);
- if (!reexport_module_sp)
- {
- reexport_module_spec.GetPlatformFileSpec().GetDirectory().Clear();
- reexport_module_sp = target.GetImages().FindFirstModule(reexport_module_spec);
- }
}
- symbol_load_addr = GetSymbolAddress(target, process, sym_ctx.symbol->GetReExportedSymbolName(), symbol_type, reexport_module_sp.get());
}
+ symbol_load_addr = GetSymbolAddress(target, process, sym_ctx.symbol->GetReExportedSymbolName(), symbol_type, reexport_module_sp.get());
}
- break;
-
- case eSymbolTypeData:
- case eSymbolTypeRuntime:
- case eSymbolTypeVariable:
- case eSymbolTypeLocal:
- case eSymbolTypeParam:
- case eSymbolTypeInvalid:
- case eSymbolTypeAbsolute:
- case eSymbolTypeException:
- case eSymbolTypeSourceFile:
- case eSymbolTypeHeaderFile:
- case eSymbolTypeObjectFile:
- case eSymbolTypeCommonBlock:
- case eSymbolTypeBlock:
- case eSymbolTypeVariableType:
- case eSymbolTypeLineEntry:
- case eSymbolTypeLineHeader:
- case eSymbolTypeScopeBegin:
- case eSymbolTypeScopeEnd:
- case eSymbolTypeAdditional:
- case eSymbolTypeCompiler:
- case eSymbolTypeInstrumentation:
- case eSymbolTypeUndefined:
- case eSymbolTypeObjCClass:
- case eSymbolTypeObjCMetaClass:
- case eSymbolTypeObjCIVar:
- symbol_load_addr = sym_address->GetLoadAddress (&target);
- break;
- }
+ }
+ break;
+
+ case eSymbolTypeData:
+ case eSymbolTypeRuntime:
+ case eSymbolTypeVariable:
+ case eSymbolTypeLocal:
+ case eSymbolTypeParam:
+ case eSymbolTypeInvalid:
+ case eSymbolTypeAbsolute:
+ case eSymbolTypeException:
+ case eSymbolTypeSourceFile:
+ case eSymbolTypeHeaderFile:
+ case eSymbolTypeObjectFile:
+ case eSymbolTypeCommonBlock:
+ case eSymbolTypeBlock:
+ case eSymbolTypeVariableType:
+ case eSymbolTypeLineEntry:
+ case eSymbolTypeLineHeader:
+ case eSymbolTypeScopeBegin:
+ case eSymbolTypeScopeEnd:
+ case eSymbolTypeAdditional:
+ case eSymbolTypeCompiler:
+ case eSymbolTypeInstrumentation:
+ case eSymbolTypeUndefined:
+ case eSymbolTypeObjCClass:
+ case eSymbolTypeObjCMetaClass:
+ case eSymbolTypeObjCIVar:
+ symbol_load_addr = sym_address.GetLoadAddress (&target);
+ break;
}
}
@@ -780,9 +777,9 @@ ClangExpressionDeclMap::FindGlobalDataSymbol (Target &target,
if (sym_ctx.symbol)
{
const Symbol *symbol = sym_ctx.symbol;
- const Address *sym_address = &symbol->GetAddress();
+ const Address sym_address = symbol->GetAddress();
- if (sym_address && sym_address->IsValid())
+ if (sym_address.IsValid())
{
switch (symbol->GetType())
{
@@ -1818,7 +1815,7 @@ ClangExpressionDeclMap::AddOneGenericVariable(NameSearchContext &context,
entity->EnableParserVars(GetParserID());
ClangExpressionVariable::ParserVars *parser_vars = entity->GetParserVars(GetParserID());
- const Address &symbol_address = symbol.GetAddress();
+ const Address symbol_address = symbol.GetAddress();
lldb::addr_t symbol_load_addr = symbol_address.GetLoadAddress(target);
//parser_vars->m_lldb_value.SetContext(Value::eContextTypeClangType, user_type.GetOpaqueQualType());
@@ -1957,7 +1954,7 @@ ClangExpressionDeclMap::AddOneFunction (NameSearchContext &context,
Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
NamedDecl *function_decl = NULL;
- const Address *fun_address = NULL;
+ Address fun_address;
ClangASTType function_clang_type;
bool is_indirect_function = false;
@@ -1982,7 +1979,7 @@ ClangExpressionDeclMap::AddOneFunction (NameSearchContext &context,
return;
}
- fun_address = &function->GetAddressRange().GetBaseAddress();
+ fun_address = function->GetAddressRange().GetBaseAddress();
ClangASTType copied_function_type = GuardedCopyType(function_clang_type);
if (copied_function_type)
@@ -2016,7 +2013,7 @@ ClangExpressionDeclMap::AddOneFunction (NameSearchContext &context,
}
else if (symbol)
{
- fun_address = &symbol->GetAddress();
+ fun_address = symbol->GetAddress();
function_decl = context.AddGenericFunDecl();
is_indirect_function = symbol->IsIndirect();
}
@@ -2029,7 +2026,7 @@ ClangExpressionDeclMap::AddOneFunction (NameSearchContext &context,
Target *target = m_parser_vars->m_exe_ctx.GetTargetPtr();
- lldb::addr_t load_addr = fun_address->GetCallableLoadAddress(target, is_indirect_function);
+ lldb::addr_t load_addr = fun_address.GetCallableLoadAddress(target, is_indirect_function);
ClangExpressionVariableSP entity(m_found_entities.CreateVariable (m_parser_vars->m_exe_ctx.GetBestExecutionContextScope (),
m_parser_vars->m_target_info.byte_order,
@@ -2052,7 +2049,7 @@ ClangExpressionDeclMap::AddOneFunction (NameSearchContext &context,
{
// We have to try finding a file address.
- lldb::addr_t file_addr = fun_address->GetFileAddress();
+ lldb::addr_t file_addr = fun_address.GetFileAddress();
parser_vars->m_lldb_value.SetValueType(Value::eValueTypeFileAddress);
parser_vars->m_lldb_value.GetScalar() = file_addr;
@@ -2068,7 +2065,7 @@ ClangExpressionDeclMap::AddOneFunction (NameSearchContext &context,
StreamString ss;
- fun_address->Dump(&ss, m_parser_vars->m_exe_ctx.GetBestExecutionContextScope(), Address::DumpStyleResolvedDescription);
+ fun_address.Dump(&ss, m_parser_vars->m_exe_ctx.GetBestExecutionContextScope(), Address::DumpStyleResolvedDescription);
log->Printf(" CEDM::FEVD[%u] Found %s function %s (description %s), returned %s",
current_id,
diff --git a/lldb/source/Expression/IRExecutionUnit.cpp b/lldb/source/Expression/IRExecutionUnit.cpp
index e0308c2ca63..96fedae59df 100644
--- a/lldb/source/Expression/IRExecutionUnit.cpp
+++ b/lldb/source/Expression/IRExecutionUnit.cpp
@@ -679,16 +679,16 @@ IRExecutionUnit::MemoryManager::getSymbolAddress(const std::string &Name)
if (sym_ctx.symbol->GetType() == lldb::eSymbolTypeUndefined)
continue;
- const Address *sym_address = &sym_ctx.symbol->GetAddress();
+ const Address sym_address = sym_ctx.symbol->GetAddress();
- if (!sym_address || !sym_address->IsValid())
+ if (!sym_address.IsValid())
continue;
symbol_load_addr = sym_ctx.symbol->ResolveCallableAddress(*target_sp);
if (symbol_load_addr == LLDB_INVALID_ADDRESS)
{
- symbol_load_addr = sym_ctx.symbol->GetAddress().GetLoadAddress(target_sp.get());
+ symbol_load_addr = sym_address.GetLoadAddress(target_sp.get());
}
}
diff --git a/lldb/source/Expression/Materializer.cpp b/lldb/source/Expression/Materializer.cpp
index 809b812f0e5..ef01feea2a4 100644
--- a/lldb/source/Expression/Materializer.cpp
+++ b/lldb/source/Expression/Materializer.cpp
@@ -1052,7 +1052,7 @@ public:
m_symbol.GetName().AsCString());
}
- Address &sym_address = m_symbol.GetAddress();
+ const Address sym_address = m_symbol.GetAddress();
ExecutionContextScope *exe_scope = map.GetBestExecutionContextScope();
diff --git a/lldb/source/Plugins/DynamicLoader/Hexagon-DYLD/DynamicLoaderHexagonDYLD.cpp b/lldb/source/Plugins/DynamicLoader/Hexagon-DYLD/DynamicLoaderHexagonDYLD.cpp
index 061283ba121..87dadd72f88 100644
--- a/lldb/source/Plugins/DynamicLoader/Hexagon-DYLD/DynamicLoaderHexagonDYLD.cpp
+++ b/lldb/source/Plugins/DynamicLoader/Hexagon-DYLD/DynamicLoaderHexagonDYLD.cpp
@@ -64,7 +64,7 @@ static lldb::addr_t findSymbolAddress( Process *proc, ConstString findName )
if ( ConstString::Compare( findName, symName ) == 0 )
{
- Address addr = sym->GetAddress( );
+ Address addr = sym->GetAddressObj( );
return addr.GetLoadAddress( & proc->GetTarget() );
}
}
diff --git a/lldb/source/Plugins/DynamicLoader/Hexagon-DYLD/HexagonDYLDRendezvous.cpp b/lldb/source/Plugins/DynamicLoader/Hexagon-DYLD/HexagonDYLDRendezvous.cpp
index 61f9b3d441c..5b9c39d2555 100644
--- a/lldb/source/Plugins/DynamicLoader/Hexagon-DYLD/HexagonDYLDRendezvous.cpp
+++ b/lldb/source/Plugins/DynamicLoader/Hexagon-DYLD/HexagonDYLDRendezvous.cpp
@@ -332,7 +332,7 @@ HexagonDYLDRendezvous::FindMetadata(const char *name, PThreadField field, uint32
if (!target.GetImages().FindSymbolsWithNameAndType (ConstString(name), eSymbolTypeAny, list))
return false;
- Address address = list[0].symbol->GetAddress();
+ Address address = list[0].symbol->GetAddressObj();
addr_t addr = address.GetLoadAddress (&target);
if (addr == LLDB_INVALID_ADDRESS)
return false;
diff --git a/lldb/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderMacOSXDYLD.cpp b/lldb/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderMacOSXDYLD.cpp
index 80fe2531845..33a375f9ac9 100644
--- a/lldb/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderMacOSXDYLD.cpp
+++ b/lldb/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderMacOSXDYLD.cpp
@@ -407,7 +407,7 @@ DynamicLoaderMacOSXDYLD::ReadDYLDInfoFromMemoryAndSetNotificationCallback(lldb::
static ConstString g_dyld_all_image_infos ("dyld_all_image_infos");
const Symbol *symbol = dyld_module_sp->FindFirstSymbolWithNameAndType (g_dyld_all_image_infos, eSymbolTypeData);
if (symbol)
- m_dyld_all_image_infos_addr = symbol->GetAddress().GetLoadAddress(&target);
+ m_dyld_all_image_infos_addr = symbol->GetLoadAddress(&target);
}
// Update all image infos
@@ -1370,7 +1370,7 @@ DynamicLoaderMacOSXDYLD::AlwaysRelyOnEHUnwindInfo (SymbolContext &sym_ctx)
ModuleSP module_sp;
if (sym_ctx.symbol)
{
- module_sp = sym_ctx.symbol->GetAddress().GetModule();
+ module_sp = sym_ctx.symbol->GetAddressRef().GetModule();
}
if (module_sp.get() == NULL && sym_ctx.function)
{
@@ -1649,12 +1649,13 @@ DynamicLoaderMacOSXDYLD::GetStepThroughTrampolinePlan (Thread &thread, bool stop
Symbol *actual_symbol = context.symbol->ResolveReExportedSymbol(*target_sp.get());
if (actual_symbol)
{
- if (actual_symbol->GetAddress().IsValid())
+ const Address actual_symbol_addr = actual_symbol->GetAddress();
+ if (actual_symbol_addr.IsValid())
{
- addresses.push_back(actual_symbol->GetAddress());
+ addresses.push_back(actual_symbol_addr);
if (log)
{
- lldb::addr_t load_addr = actual_symbol->GetAddress().GetLoadAddress(target_sp.get());
+ lldb::addr_t load_addr = actual_symbol_addr.GetLoadAddress(target_sp.get());
log->Printf ("Found a re-exported symbol: %s at 0x%" PRIx64 ".",
actual_symbol->GetName().GetCString(), load_addr);
}
@@ -1720,7 +1721,8 @@ DynamicLoaderMacOSXDYLD::GetStepThroughTrampolinePlan (Thread &thread, bool stop
if (symbol && symbol->IsIndirect())
{
Error error;
- addr_t resolved_addr = thread.GetProcess()->ResolveIndirectFunction(&symbol->GetAddress(), error);
+ Address symbol_address = symbol->GetAddress();
+ addr_t resolved_addr = thread.GetProcess()->ResolveIndirectFunction(&symbol_address, error);
if (error.Success())
{
load_addrs.push_back(resolved_addr);
diff --git a/lldb/source/Plugins/InstrumentationRuntime/AddressSanitizer/AddressSanitizerRuntime.cpp b/lldb/source/Plugins/InstrumentationRuntime/AddressSanitizer/AddressSanitizerRuntime.cpp
index 54c6834518a..9b72ceb71bd 100644
--- a/lldb/source/Plugins/InstrumentationRuntime/AddressSanitizer/AddressSanitizerRuntime.cpp
+++ b/lldb/source/Plugins/InstrumentationRuntime/AddressSanitizer/AddressSanitizerRuntime.cpp
@@ -287,11 +287,11 @@ AddressSanitizerRuntime::Activate()
if (symbol == NULL)
return;
- if (!symbol->GetAddress().IsValid())
+ if (!symbol->ValueIsAddress() || !symbol->GetAddressRef().IsValid())
return;
Target &target = m_process->GetTarget();
- addr_t symbol_address = symbol->GetAddress().GetOpcodeLoadAddress(&target);
+ addr_t symbol_address = symbol->GetAddressRef().GetOpcodeLoadAddress(&target);
if (symbol_address == LLDB_INVALID_ADDRESS)
return;
diff --git a/lldb/source/Plugins/JITLoader/GDB/JITLoaderGDB.cpp b/lldb/source/Plugins/JITLoader/GDB/JITLoaderGDB.cpp
index b9c71ad1ba4..8e454e712fe 100644
--- a/lldb/source/Plugins/JITLoader/GDB/JITLoaderGDB.cpp
+++ b/lldb/source/Plugins/JITLoader/GDB/JITLoaderGDB.cpp
@@ -436,10 +436,10 @@ JITLoaderGDB::GetSymbolAddress(ModuleList &module_list, const ConstString &name,
SymbolContext sym_ctx;
target_symbols.GetContextAtIndex(0, sym_ctx);
- const Address *jit_descriptor_addr = &sym_ctx.symbol->GetAddress();
- if (!jit_descriptor_addr || !jit_descriptor_addr->IsValid())
+ const Address jit_descriptor_addr = sym_ctx.symbol->GetAddress();
+ if (!jit_descriptor_addr.IsValid())
return LLDB_INVALID_ADDRESS;
- const addr_t jit_addr = jit_descriptor_addr->GetLoadAddress(&target);
+ const addr_t jit_addr = jit_descriptor_addr.GetLoadAddress(&target);
return jit_addr;
}
diff --git a/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV1.cpp b/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV1.cpp
index 792886f1bcf..9f0f6aa3c48 100644
--- a/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV1.cpp
+++ b/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV1.cpp
@@ -299,13 +299,13 @@ AppleObjCRuntimeV1::GetISAHashTablePointer ()
static ConstString g_objc_debug_class_hash("_objc_debug_class_hash");
const Symbol *symbol = objc_module_sp->FindFirstSymbolWithNameAndType(g_objc_debug_class_hash, lldb::eSymbolTypeData);
- if (symbol)
+ if (symbol && symbol->ValueIsAddress())
{
Process *process = GetProcess();
if (process)
{
- lldb::addr_t objc_debug_class_hash_addr = symbol->GetAddress().GetLoadAddress(&process->GetTarget());
+ lldb::addr_t objc_debug_class_hash_addr = symbol->GetAddressRef().GetLoadAddress(&process->GetTarget());
if (objc_debug_class_hash_addr != LLDB_INVALID_ADDRESS)
{
diff --git a/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV2.cpp b/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV2.cpp
index 02d9350ba90..54a253c8200 100644
--- a/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV2.cpp
+++ b/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV2.cpp
@@ -321,9 +321,9 @@ ExtractRuntimeGlobalSymbol (Process* process,
if (!byte_size)
byte_size = process->GetAddressByteSize();
const Symbol *symbol = module_sp->FindFirstSymbolWithNameAndType(name, lldb::eSymbolTypeData);
- if (symbol)
+ if (symbol && symbol->ValueIsAddress())
{
- lldb::addr_t symbol_load_addr = symbol->GetAddress().GetLoadAddress(&process->GetTarget());
+ lldb::addr_t symbol_load_addr = symbol->GetAddressRef().GetLoadAddress(&process->GetTarget());
if (symbol_load_addr != LLDB_INVALID_ADDRESS)
{
if (read_value)
@@ -815,7 +815,7 @@ AppleObjCRuntimeV2::GetByteOffsetForIvar (ClangASTType &parent_ast_type, const c
if (sc_list.GetSize() == 1 && sc_list.GetContextAtIndex(0, ivar_offset_symbol))
{
if (ivar_offset_symbol.symbol)
- ivar_offset_address = ivar_offset_symbol.symbol->GetAddress().GetLoadAddress (&target);
+ ivar_offset_address = ivar_offset_symbol.symbol->GetLoadAddress (&target);
}
//----------------------------------------------------------------------
@@ -1191,7 +1191,7 @@ AppleObjCRuntimeV2::GetISAHashTablePointer ()
const Symbol *symbol = objc_module_sp->FindFirstSymbolWithNameAndType(g_gdb_objc_realized_classes, lldb::eSymbolTypeAny);
if (symbol)
{
- lldb::addr_t gdb_objc_realized_classes_ptr = symbol->GetAddress().GetLoadAddress(&process->GetTarget());
+ lldb::addr_t gdb_objc_realized_classes_ptr = symbol->GetLoadAddress(&process->GetTarget());
if (gdb_objc_realized_classes_ptr != LLDB_INVALID_ADDRESS)
{
diff --git a/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCTrampolineHandler.cpp b/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCTrampolineHandler.cpp
index dd2d0e035d9..5d82f16722e 100644
--- a/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCTrampolineHandler.cpp
+++ b/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCTrampolineHandler.cpp
@@ -471,10 +471,7 @@ AppleObjCTrampolineHandler::AppleObjCVTables::InitializeVTableSymbols ()
eSymbolTypeData);
if (trampoline_symbol != NULL)
{
- if (!trampoline_symbol->GetAddress().IsValid())
- return false;
-
- m_trampoline_header = trampoline_symbol->GetAddress().GetLoadAddress(&target);
+ m_trampoline_header = trampoline_symbol->GetLoadAddress(&target);
if (m_trampoline_header == LLDB_INVALID_ADDRESS)
return false;
@@ -484,10 +481,11 @@ AppleObjCTrampolineHandler::AppleObjCVTables::InitializeVTableSymbols ()
eSymbolTypeCode);
if (changed_symbol != NULL)
{
- if (!changed_symbol->GetAddress().IsValid())
+ const Address changed_symbol_addr = changed_symbol->GetAddress();
+ if (!changed_symbol_addr.IsValid())
return false;
- lldb::addr_t changed_addr = changed_symbol->GetAddress().GetOpcodeLoadAddress (&target);
+ lldb::addr_t changed_addr = changed_symbol_addr.GetOpcodeLoadAddress (&target);
if (changed_addr != LLDB_INVALID_ADDRESS)
{
BreakpointSP trampolines_changed_bp_sp = target.CreateBreakpoint (changed_addr, true, false);
@@ -703,13 +701,13 @@ AppleObjCTrampolineHandler::AppleObjCTrampolineHandler (const ProcessSP &process
{
ConstString name_const_str(g_dispatch_functions[i].name);
const Symbol *msgSend_symbol = m_objc_module_sp->FindFirstSymbolWithNameAndType (name_const_str, eSymbolTypeCode);
- if (msgSend_symbol)
+ if (msgSend_symbol && msgSend_symbol->ValueIsAddress())
{
// FixMe: Make g_dispatch_functions static table of DispatchFunctions, and have the map be address->index.
// Problem is we also need to lookup the dispatch function. For now we could have a side table of stret & non-stret
// dispatch functions. If that's as complex as it gets, we're fine.
- lldb::addr_t sym_addr = msgSend_symbol->GetAddress().GetOpcodeLoadAddress(target);
+ lldb::addr_t sym_addr = msgSend_symbol->GetAddressRef().GetOpcodeLoadAddress(target);
m_msgSend_map.insert(std::pair<lldb::addr_t, int>(sym_addr, i));
}
diff --git a/lldb/source/Plugins/LanguageRuntime/RenderScript/RenderScriptRuntime/RenderScriptRuntime.cpp b/lldb/source/Plugins/LanguageRuntime/RenderScript/RenderScriptRuntime/RenderScriptRuntime.cpp
index da36b19f321..2490cf31409 100644
--- a/lldb/source/Plugins/LanguageRuntime/RenderScript/RenderScriptRuntime/RenderScriptRuntime.cpp
+++ b/lldb/source/Plugins/LanguageRuntime/RenderScript/RenderScriptRuntime/RenderScriptRuntime.cpp
@@ -422,7 +422,7 @@ RenderScriptRuntime::LoadRuntimeHooks(lldb::ModuleSP module, ModuleKind kind)
const Symbol *sym = module->FindFirstSymbolWithNameAndType(ConstString(hook_defn->symbol_name), eSymbolTypeCode);
- addr_t addr = sym->GetAddress().GetLoadAddress(&target);
+ addr_t addr = sym->GetLoadAddress(&target);
if (addr == LLDB_INVALID_ADDRESS)
{
if(log)
@@ -542,7 +542,7 @@ RenderScriptRuntime::LoadModule(const lldb::ModuleSP &module_sp)
Error error;
uint32_t flag = 0x00000001U;
Target &target = GetProcess()->GetTarget();
- addr_t addr = debug_present->GetAddress().GetLoadAddress(&target);
+ addr_t addr = debug_present->GetLoadAddress(&target);
GetProcess()->WriteMemory(addr, &flag, sizeof(flag), error);
if(error.Success())
{
@@ -597,7 +597,7 @@ RSModuleDescriptor::ParseRSInfo()
const Symbol *info_sym = m_module->FindFirstSymbolWithNameAndType(ConstString(".rs.info"), eSymbolTypeData);
if (info_sym)
{
- const addr_t addr = info_sym->GetAddress().GetFileAddress();
+ const addr_t addr = info_sym->GetAddressRef().GetFileAddress();
const addr_t size = info_sym->GetByteSize();
const FileSpec fs = m_module->GetFileSpec();
@@ -809,7 +809,7 @@ RenderScriptRuntime::AttemptBreakpointAtKernelName(Stream &strm, const char* nam
}
}
- addr_t bp_addr = kernel_sym->GetAddress().GetLoadAddress(&GetProcess()->GetTarget());
+ addr_t bp_addr = kernel_sym->GetLoadAddress(&GetProcess()->GetTarget());
if (bp_addr == LLDB_INVALID_ADDRESS)
{
error.SetErrorStringWithFormat("Could not locate load address for symbols of kernel '%s'.", name);
diff --git a/lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp b/lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp
index bdc13e73260..1ceaa2c3761 100644
--- a/lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp
+++ b/lldb/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp
@@ -2381,7 +2381,7 @@ ObjectFileELF::RelocateSection(Symtab* symtab, const ELFHeader *hdr, const ELFSe
symbol = symtab->FindSymbolByID(reloc_symbol(rel));
if (symbol)
{
- addr_t value = symbol->GetAddress().GetFileAddress();
+ addr_t value = symbol->GetAddressRef().GetFileAddress();
DataBufferSP& data_buffer_sp = debug_data.GetSharedDataBuffer();
uint64_t* dst = reinterpret_cast<uint64_t*>(data_buffer_sp->GetBytes() + rel_section->GetFileOffset() + ELFRelocation::RelocOffset64(rel));
*dst = value + ELFRelocation::RelocAddend64(rel);
@@ -2394,7 +2394,7 @@ ObjectFileELF::RelocateSection(Symtab* symtab, const ELFHeader *hdr, const ELFSe
symbol = symtab->FindSymbolByID(reloc_symbol(rel));
if (symbol)
{
- addr_t value = symbol->GetAddress().GetFileAddress();
+ addr_t value = symbol->GetAddressRef().GetFileAddress();
value += ELFRelocation::RelocAddend32(rel);
assert((reloc_type(rel) == R_X86_64_32 && (value <= UINT32_MAX)) ||
(reloc_type(rel) == R_X86_64_32S &&
diff --git a/lldb/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp b/lldb/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp
index c61f871cdbd..511d73d2226 100644
--- a/lldb/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp
+++ b/lldb/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp
@@ -1271,7 +1271,7 @@ ObjectFileMachO::GetAddressClass (lldb::addr_t file_addr)
{
if (symbol->ValueIsAddress())
{
- SectionSP section_sp (symbol->GetAddress().GetSection());
+ SectionSP section_sp (symbol->GetAddressRef().GetSection());
if (section_sp)
{
const lldb::SectionType section_type = section_sp->GetType();
@@ -3521,8 +3521,8 @@ ObjectFileMachO::ParseSymtab ()
m_nlist_idx_to_sym_idx[nlist_idx] = GSYM_sym_idx;
// Copy the address, because often the N_GSYM address has an invalid address of zero
// when the global is a common symbol
- sym[GSYM_sym_idx].GetAddress().SetSection (symbol_section);
- sym[GSYM_sym_idx].GetAddress().SetOffset (symbol_value);
+ sym[GSYM_sym_idx].GetAddressRef().SetSection (symbol_section);
+ sym[GSYM_sym_idx].GetAddressRef().SetOffset (symbol_value);
// We just need the flags from the linker symbol, so put these flags
// into the N_GSYM flags to avoid duplicate symbols in the symbol table
sym[GSYM_sym_idx].SetFlags (nlist.n_type << 16 | nlist.n_desc);
@@ -3537,8 +3537,8 @@ ObjectFileMachO::ParseSymtab ()
sym[sym_idx].SetType (type);
if (set_value)
{
- sym[sym_idx].GetAddress().SetSection (symbol_section);
- sym[sym_idx].GetAddress().SetOffset (symbol_value);
+ sym[sym_idx].GetAddressRef().SetSection (symbol_section);
+ sym[sym_idx].GetAddressRef().SetOffset (symbol_value);
}
sym[sym_idx].SetFlags (nlist.n_type << 16 | nlist.n_desc);
@@ -4364,8 +4364,8 @@ ObjectFileMachO::ParseSymtab ()
m_nlist_idx_to_sym_idx[nlist_idx] = GSYM_sym_idx;
// Copy the address, because often the N_GSYM address has an invalid address of zero
// when the global is a common symbol
- sym[GSYM_sym_idx].GetAddress().SetSection (symbol_section);
- sym[GSYM_sym_idx].GetAddress().SetOffset (symbol_value);
+ sym[GSYM_sym_idx].GetAddressRef().SetSection (symbol_section);
+ sym[GSYM_sym_idx].GetAddressRef().SetOffset (symbol_value);
// We just need the flags from the linker symbol, so put these flags
// into the N_GSYM flags to avoid duplicate symbols in the symbol table
sym[GSYM_sym_idx].SetFlags (nlist.n_type << 16 | nlist.n_desc);
@@ -4380,8 +4380,8 @@ ObjectFileMachO::ParseSymtab ()
sym[sym_idx].SetType (type);
if (set_value)
{
- sym[sym_idx].GetAddress().SetSection (symbol_section);
- sym[sym_idx].GetAddress().SetOffset (symbol_value);
+ sym[sym_idx].GetAddressRef().SetSection (symbol_section);
+ sym[sym_idx].GetAddressRef().SetOffset (symbol_value);
}
sym[sym_idx].SetFlags (nlist.n_type << 16 | nlist.n_desc);
@@ -4475,7 +4475,7 @@ ObjectFileMachO::ParseSymtab ()
sym[sym_idx].GetMangled().SetDemangledName(ConstString(synthetic_function_symbol));
sym[sym_idx].SetType (eSymbolTypeCode);
sym[sym_idx].SetIsSynthetic (true);
- sym[sym_idx].GetAddress() = symbol_addr;
+ sym[sym_idx].GetAddressRef() = symbol_addr;
if (symbol_flags)
sym[sym_idx].SetFlags (symbol_flags);
if (symbol_byte_size)
@@ -4559,7 +4559,7 @@ ObjectFileMachO::ParseSymtab ()
else
stub_symbol->SetType (eSymbolTypeResolver);
stub_symbol->SetExternal (false);
- stub_symbol->GetAddress() = so_addr;
+ stub_symbol->GetAddressRef() = so_addr;
stub_symbol->SetByteSize (symbol_stub_byte_size);
}
else
@@ -4578,7 +4578,7 @@ ObjectFileMachO::ParseSymtab ()
else
sym[sym_idx].SetType (eSymbolTypeResolver);
sym[sym_idx].SetIsSynthetic (true);
- sym[sym_idx].GetAddress() = so_addr;
+ sym[sym_idx].GetAddressRef() = so_addr;
sym[sym_idx].SetByteSize (symbol_stub_byte_size);
++sym_idx;
}
diff --git a/lldb/source/Plugins/ObjectFile/PECOFF/ObjectFilePECOFF.cpp b/lldb/source/Plugins/ObjectFile/PECOFF/ObjectFilePECOFF.cpp
index 5f7935e1275..8189f10bd30 100644
--- a/lldb/source/Plugins/ObjectFile/PECOFF/ObjectFilePECOFF.cpp
+++ b/lldb/source/Plugins/ObjectFile/PECOFF/ObjectFilePECOFF.cpp
@@ -574,7 +574,7 @@ ObjectFilePECOFF::GetSymtab()
if ((int16_t)symbol.sect >= 1)
{
Address symbol_addr(sect_list->GetSectionAtIndex(symbol.sect-1), symbol.value);
- symbols[i].GetAddress() = symbol_addr;
+ symbols[i].GetAddressRef() = symbol_addr;
}
if (symbol.naux > 0)
@@ -633,7 +633,7 @@ ObjectFilePECOFF::GetSymtab()
Address symbol_addr(m_coff_header_opt.image_base + function_rva, sect_list);
symbols[i].GetMangled().SetValue(ConstString(symbol_name.c_str()));
- symbols[i].GetAddress() = symbol_addr;
+ symbols[i].GetAddressRef() = symbol_addr;
symbols[i].SetType(lldb::eSymbolTypeCode);
symbols[i].SetDebug(true);
}
diff --git a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp
index f487ae94192..167198950fa 100644
--- a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp
+++ b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp
@@ -100,6 +100,7 @@ GDBRemoteCommunicationClient::GDBRemoteCommunicationClient() :
m_supports_QEnvironment (true),
m_supports_QEnvironmentHexEncoded (true),
m_supports_qSymbol (true),
+ m_supports_jThreadsInfo (true),
m_curr_pid (LLDB_INVALID_PROCESS_ID),
m_curr_tid (LLDB_INVALID_THREAD_ID),
m_curr_tid_run (LLDB_INVALID_THREAD_ID),
@@ -604,6 +605,32 @@ GDBRemoteCommunicationClient::GetpPacketSupported (lldb::tid_t tid)
return m_supports_p;
}
+StructuredData::ObjectSP
+GDBRemoteCommunicationClient::GetThreadsInfo()
+{
+ // Get information on all threads at one using the "jThreadsInfo" packet
+ StructuredData::ObjectSP object_sp;
+
+ if (m_supports_jThreadsInfo)
+ {
+ StringExtractorGDBRemote response;
+ m_supports_jThreadExtendedInfo = eLazyBoolNo;
+ if (SendPacketAndWaitForResponse("jThreadsInfo", response, false) == PacketResult::Success)
+ {
+ if (response.IsUnsupportedResponse())
+ {
+ m_supports_jThreadsInfo = false;
+ }
+ else if (!response.Empty())
+ {
+ object_sp = StructuredData::ParseJSON (response.GetStringRef());
+ }
+ }
+ }
+ return object_sp;
+}
+
+
bool
GDBRemoteCommunicationClient::GetThreadExtendedInfoSupported ()
{
@@ -4296,11 +4323,52 @@ GDBRemoteCommunicationClient::ServeSymbolLookups(lldb_private::Process *process)
lldb_private::SymbolContextList sc_list;
if (process->GetTarget().GetImages().FindSymbolsWithNameAndType(ConstString(symbol_name), eSymbolTypeAny, sc_list))
{
- SymbolContext sc;
- if (sc_list.GetContextAtIndex(0, sc))
+ const size_t num_scs = sc_list.GetSize();
+ for (size_t sc_idx=0; sc_idx<num_scs && symbol_load_addr == LLDB_INVALID_ADDRESS; ++sc_idx)
{
- if (sc.symbol)
- symbol_load_addr = sc.symbol->GetAddress().GetLoadAddress(&process->GetTarget());
+ SymbolContext sc;
+ if (sc_list.GetContextAtIndex(sc_idx, sc))
+ {
+ if (sc.symbol)
+ {
+ switch (sc.symbol->GetType())
+ {
+ case eSymbolTypeInvalid:
+ case eSymbolTypeAbsolute:
+ case eSymbolTypeUndefined:
+ case eSymbolTypeSourceFile:
+ case eSymbolTypeHeaderFile:
+ case eSymbolTypeObjectFile:
+ case eSymbolTypeCommonBlock:
+ case eSymbolTypeBlock:
+ case eSymbolTypeLocal:
+ case eSymbolTypeParam:
+ case eSymbolTypeVariable:
+ case eSymbolTypeVariableType:
+ case eSymbolTypeLineEntry:
+ case eSymbolTypeLineHeader:
+ case eSymbolTypeScopeBegin:
+ case eSymbolTypeScopeEnd:
+ case eSymbolTypeAdditional:
+ case eSymbolTypeCompiler:
+ case eSymbolTypeInstrumentation:
+ case eSymbolTypeTrampoline:
+ break;
+
+ case eSymbolTypeCode:
+ case eSymbolTypeResolver:
+ case eSymbolTypeData:
+ case eSymbolTypeRuntime:
+ case eSymbolTypeException:
+ case eSymbolTypeObjCClass:
+ case eSymbolTypeObjCMetaClass:
+ case eSymbolTypeObjCIVar:
+ case eSymbolTypeReExported:
+ symbol_load_addr = sc.symbol->GetLoadAddress(&process->GetTarget());
+ break;
+ }
+ }
+ }
}
}
// This is the normal path where our symbol lookup was successful and we want
diff --git a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.h b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.h
index 07a3bd93321..28983b7574b 100644
--- a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.h
+++ b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.h
@@ -17,6 +17,7 @@
// Other libraries and framework includes
// Project includes
#include "lldb/Core/ArchSpec.h"
+#include "lldb/Core/StructuredData.h"
#include "lldb/Target/Process.h"
#include "GDBRemoteCommunication.h"
@@ -542,6 +543,9 @@ public:
bool
AvoidGPackets(ProcessGDBRemote *process);
+ StructuredData::ObjectSP
+ GetThreadsInfo();
+
bool
GetThreadExtendedInfoSupported();
@@ -624,7 +628,8 @@ protected:
m_supports_z4:1,
m_supports_QEnvironment:1,
m_supports_QEnvironmentHexEncoded:1,
- m_supports_qSymbol:1;
+ m_supports_qSymbol:1,
+ m_supports_jThreadsInfo:1;
lldb::pid_t m_curr_pid;
lldb::tid_t m_curr_tid; // Current gdb remote protocol thread index for all other operations
diff --git a/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp b/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp
index 2b7ff2427b9..a7e4d8c95e4 100644
--- a/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp
+++ b/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp
@@ -378,6 +378,7 @@ ProcessGDBRemote::ProcessGDBRemote(Target& target, Listener &listener) :
m_async_broadcaster (NULL, "lldb.process.gdb-remote.async-broadcaster"),
m_async_thread_state_mutex(Mutex::eMutexTypeRecursive),
m_thread_ids (),
+ m_threads_info_sp (),
m_continue_c_tids (),
m_continue_C_tids (),
m_continue_s_tids (),
@@ -1795,6 +1796,362 @@ ProcessGDBRemote::UpdateThreadList (ThreadList &old_thread_list, ThreadList &new
return true;
}
+bool
+ProcessGDBRemote::CalculateThreadStopInfo (ThreadGDBRemote *thread)
+{
+ // See if we got thread stop infos for all threads via the "jThreadsInfo" packet
+ if (m_threads_info_sp)
+ {
+ StructuredData::Array *thread_infos = m_threads_info_sp->GetAsArray();
+ if (thread_infos)
+ {
+ lldb::tid_t tid;
+ const size_t n = thread_infos->GetSize();
+ for (size_t i=0; i<n; ++i)
+ {
+ StructuredData::Dictionary *thread_dict = thread_infos->GetItemAtIndex(i)->GetAsDictionary();
+ if (thread_dict)
+ {
+ if (thread_dict->GetValueForKeyAsInteger<lldb::tid_t>("tid", tid, LLDB_INVALID_THREAD_ID))
+ {
+ if (tid == thread->GetID())
+ return SetThreadStopInfo(thread_dict);
+ }
+ }
+ }
+ }
+ }
+
+ // Fall back to using the qThreadStopInfo packet
+ StringExtractorGDBRemote stop_packet;
+ if (GetGDBRemote().GetThreadStopInfo(thread->GetProtocolID(), stop_packet))
+ return SetThreadStopInfo (stop_packet) == eStateStopped;
+ return false;
+}
+
+
+ThreadSP
+ProcessGDBRemote::SetThreadStopInfo (lldb::tid_t tid,
+ ExpeditedRegisterMap &expedited_register_map,
+ uint8_t signo,
+ const std::string &thread_name,
+ const std::string &reason,
+ const std::string &description,
+ uint32_t exc_type,
+ const std::vector<addr_t> &exc_data,
+ addr_t thread_dispatch_qaddr)
+{
+ ThreadSP thread_sp;
+ if (tid != LLDB_INVALID_THREAD_ID)
+ {
+ // Scope for "locker" below
+ {
+ // m_thread_list_real does have its own mutex, but we need to
+ // hold onto the mutex between the call to m_thread_list_real.FindThreadByID(...)
+ // and the m_thread_list_real.AddThread(...) so it doesn't change on us
+ Mutex::Locker locker (m_thread_list_real.GetMutex ());
+ thread_sp = m_thread_list_real.FindThreadByProtocolID(tid, false);
+
+ if (!thread_sp)
+ {
+ // Create the thread if we need to
+ thread_sp.reset (new ThreadGDBRemote (*this, tid));
+ m_thread_list_real.AddThread(thread_sp);
+ }
+ }
+
+ if (thread_sp)
+ {
+ ThreadGDBRemote *gdb_thread = static_cast<ThreadGDBRemote *> (thread_sp.get());
+ gdb_thread->GetRegisterContext()->InvalidateIfNeeded(true);
+
+ for (const auto &pair : expedited_register_map)
+ {
+ StringExtractor reg_value_extractor;
+ reg_value_extractor.GetStringRef() = pair.second;
+ gdb_thread->PrivateSetRegisterValue (pair.first, reg_value_extractor);
+ }
+
+ // Clear the stop info just in case we don't set it to anything
+ thread_sp->SetStopInfo (StopInfoSP());
+ thread_sp->SetName (thread_name.empty() ? NULL : thread_name.c_str());
+
+ gdb_thread->SetThreadDispatchQAddr (thread_dispatch_qaddr);
+ if (exc_type != 0)
+ {
+ const size_t exc_data_size = exc_data.size();
+
+ thread_sp->SetStopInfo (StopInfoMachException::CreateStopReasonWithMachException (*thread_sp,
+ exc_type,
+ exc_data_size,
+ exc_data_size >= 1 ? exc_data[0] : 0,
+ exc_data_size >= 2 ? exc_data[1] : 0,
+ exc_data_size >= 3 ? exc_data[2] : 0));
+ }
+ else
+ {
+ bool handled = false;
+ bool did_exec = false;
+ if (!reason.empty())
+ {
+ if (reason.compare("trace") == 0)
+ {
+ thread_sp->SetStopInfo (StopInfo::CreateStopReasonToTrace (*thread_sp));
+ handled = true;
+ }
+ else if (reason.compare("breakpoint") == 0)
+ {
+ addr_t pc = thread_sp->GetRegisterContext()->GetPC();
+ lldb::BreakpointSiteSP bp_site_sp = thread_sp->GetProcess()->GetBreakpointSiteList().FindByAddress(pc);
+ if (bp_site_sp)
+ {
+ // If the breakpoint is for this thread, then we'll report the hit, but if it is for another thread,
+ // we can just report no reason. We don't need to worry about stepping over the breakpoint here, that
+ // will be taken care of when the thread resumes and notices that there's a breakpoint under the pc.
+ handled = true;
+ if (bp_site_sp->ValidForThisThread (thread_sp.get()))
+ {
+ thread_sp->SetStopInfo (StopInfo::CreateStopReasonWithBreakpointSiteID (*thread_sp, bp_site_sp->GetID()));
+ }
+ else
+ {
+ StopInfoSP invalid_stop_info_sp;
+ thread_sp->SetStopInfo (invalid_stop_info_sp);
+ }
+ }
+ }
+ else if (reason.compare("trap") == 0)
+ {
+ // Let the trap just use the standard signal stop reason below...
+ }
+ else if (reason.compare("watchpoint") == 0)
+ {
+ StringExtractor desc_extractor(description.c_str());
+ addr_t wp_addr = desc_extractor.GetU64(LLDB_INVALID_ADDRESS);
+ uint32_t wp_index = desc_extractor.GetU32(LLDB_INVALID_INDEX32);
+ watch_id_t watch_id = LLDB_INVALID_WATCH_ID;
+ if (wp_addr != LLDB_INVALID_ADDRESS)
+ {
+ WatchpointSP wp_sp = GetTarget().GetWatchpointList().FindByAddress(wp_addr);
+ if (wp_sp)
+ {
+ wp_sp->SetHardwareIndex(wp_index);
+ watch_id = wp_sp->GetID();
+ }
+ }
+ if (watch_id == LLDB_INVALID_WATCH_ID)
+ {
+ Log *log (ProcessGDBRemoteLog::GetLogIfAllCategoriesSet (GDBR_LOG_WATCHPOINTS));
+ if (log) log->Printf ("failed to find watchpoint");
+ }
+ thread_sp->SetStopInfo (StopInfo::CreateStopReasonWithWatchpointID (*thread_sp, watch_id));
+ handled = true;
+ }
+ else if (reason.compare("exception") == 0)
+ {
+ thread_sp->SetStopInfo (StopInfo::CreateStopReasonWithException(*thread_sp, description.c_str()));
+ handled = true;
+ }
+ else if (reason.compare("exec") == 0)
+ {
+ did_exec = true;
+ thread_sp->SetStopInfo (StopInfo::CreateStopReasonWithExec(*thread_sp));
+ handled = true;
+ }
+ }
+
+ if (!handled && signo && did_exec == false)
+ {
+ if (signo == SIGTRAP)
+ {
+ // Currently we are going to assume SIGTRAP means we are either
+ // hitting a breakpoint or hardware single stepping.
+ handled = true;
+ addr_t pc = thread_sp->GetRegisterContext()->GetPC() + m_breakpoint_pc_offset;
+ lldb::BreakpointSiteSP bp_site_sp = thread_sp->GetProcess()->GetBreakpointSiteList().FindByAddress(pc);
+
+ if (bp_site_sp)
+ {
+ // If the breakpoint is for this thread, then we'll report the hit, but if it is for another thread,
+ // we can just report no reason. We don't need to worry about stepping over the breakpoint here, that
+ // will be taken care of when the thread resumes and notices that there's a breakpoint under the pc.
+ if (bp_site_sp->ValidForThisThread (thread_sp.get()))
+ {
+ if(m_breakpoint_pc_offset != 0)
+ thread_sp->GetRegisterContext()->SetPC(pc);
+ thread_sp->SetStopInfo (StopInfo::CreateStopReasonWithBreakpointSiteID (*thread_sp, bp_site_sp->GetID()));
+ }
+ else
+ {
+ StopInfoSP invalid_stop_info_sp;
+ thread_sp->SetStopInfo (invalid_stop_info_sp);
+ }
+ }
+ else
+ {
+ // If we were stepping then assume the stop was the result of the trace. If we were
+ // not stepping then report the SIGTRAP.
+ // FIXME: We are still missing the case where we single step over a trap instruction.
+ if (thread_sp->GetTemporaryResumeState() == eStateStepping)
+ thread_sp->SetStopInfo (StopInfo::CreateStopReasonToTrace (*thread_sp));
+ else
+ thread_sp->SetStopInfo (StopInfo::CreateStopReasonWithSignal(*thread_sp, signo, description.c_str()));
+ }
+ }
+ if (!handled)
+ thread_sp->SetStopInfo (StopInfo::CreateStopReasonWithSignal (*thread_sp, signo, description.c_str()));
+ }
+
+ if (!description.empty())
+ {
+ lldb::StopInfoSP stop_info_sp (thread_sp->GetStopInfo ());
+ if (stop_info_sp)
+ {
+ const char *stop_info_desc = stop_info_sp->GetDescription();
+ if (!stop_info_desc || !stop_info_desc[0])
+ stop_info_sp->SetDescription (description.c_str());
+ }
+ else
+ {
+ thread_sp->SetStopInfo (StopInfo::CreateStopReasonWithException (*thread_sp, description.c_str()));
+ }
+ }
+ }
+ }
+ }
+ return thread_sp;
+}
+
+StateType
+ProcessGDBRemote::SetThreadStopInfo (StructuredData::Dictionary *thread_dict)
+{
+ static ConstString g_key_tid("tid");
+ static ConstString g_key_name("name");
+ static ConstString g_key_reason("reason");
+ static ConstString g_key_metype("metype");
+ static ConstString g_key_medata("medata");
+ static ConstString g_key_qaddr("qaddr");
+ static ConstString g_key_registers("registers");
+ static ConstString g_key_memory("memory");
+ static ConstString g_key_address("address");
+ static ConstString g_key_bytes("bytes");
+ static ConstString g_key_description("description");
+
+ // Stop with signal and thread info
+ lldb::tid_t tid = LLDB_INVALID_THREAD_ID;
+ uint8_t signo = 0;
+ std::string value;
+ std::string thread_name;
+ std::string reason;
+ std::string description;
+ uint32_t exc_type = 0;
+ std::vector<addr_t> exc_data;
+ addr_t thread_dispatch_qaddr = LLDB_INVALID_ADDRESS;
+ ExpeditedRegisterMap expedited_register_map;
+ // Iterate through all of the thread dictionary key/value pairs from the structured data dictionary
+
+ thread_dict->ForEach([this, &tid, &expedited_register_map, &thread_name, &signo, &reason, &description, &exc_type, &exc_data, &thread_dispatch_qaddr](ConstString key, StructuredData::Object* object) -> bool
+ {
+ if (key == g_key_tid)
+ {
+ // thread in big endian hex
+ tid = object->GetIntegerValue(LLDB_INVALID_THREAD_ID);
+ }
+ else if (key == g_key_metype)
+ {
+ // exception type in big endian hex
+ exc_type = object->GetIntegerValue(0);
+ }
+ else if (key == g_key_medata)
+ {
+ // exception data in big endian hex
+ StructuredData::Array *array = object->GetAsArray();
+ if (array)
+ {
+ array->ForEach([&exc_data](StructuredData::Object* object) -> bool {
+ exc_data.push_back(object->GetIntegerValue());
+ return true; // Keep iterating through all array items
+ });
+ }
+ }
+ else if (key == g_key_name)
+ {
+ thread_name = std::move(object->GetStringValue());
+ }
+ else if (key == g_key_qaddr)
+ {
+ thread_dispatch_qaddr = object->GetIntegerValue(LLDB_INVALID_ADDRESS);
+ }
+ else if (key == g_key_reason)
+ {
+ reason = std::move(object->GetStringValue());
+ }
+ else if (key == g_key_description)
+ {
+ description = std::move(object->GetStringValue());
+ }
+ else if (key == g_key_registers)
+ {
+ StructuredData::Dictionary *registers_dict = object->GetAsDictionary();
+
+ if (registers_dict)
+ {
+ registers_dict->ForEach([&expedited_register_map](ConstString key, StructuredData::Object* object) -> bool {
+ const uint32_t reg = StringConvert::ToUInt32 (key.GetCString(), UINT32_MAX, 10);
+ if (reg != UINT32_MAX)
+ expedited_register_map[reg] = std::move(object->GetStringValue());
+ return true; // Keep iterating through all array items
+ });
+ }
+ }
+ else if (key == g_key_memory)
+ {
+ StructuredData::Array *array = object->GetAsArray();
+ if (array)
+ {
+ array->ForEach([this](StructuredData::Object* object) -> bool {
+ StructuredData::Dictionary *mem_cache_dict = object->GetAsDictionary();
+ if (mem_cache_dict)
+ {
+ lldb::addr_t mem_cache_addr = LLDB_INVALID_ADDRESS;
+ if (mem_cache_dict->GetValueForKeyAsInteger<lldb::addr_t>("address", mem_cache_addr))
+ {
+ if (mem_cache_addr != LLDB_INVALID_ADDRESS)
+ {
+ StringExtractor bytes;
+ if (mem_cache_dict->GetValueForKeyAsString("bytes", bytes.GetStringRef()))
+ {
+ bytes.SetFilePos(0);
+
+ const size_t byte_size = bytes.GetStringRef().size()/2;
+ DataBufferSP data_buffer_sp(new DataBufferHeap(byte_size, 0));
+ const size_t bytes_copied = bytes.GetHexBytes (data_buffer_sp->GetBytes(), byte_size, 0);
+ if (bytes_copied == byte_size)
+ m_memory_cache.AddL1CacheData(mem_cache_addr, data_buffer_sp);
+ }
+ }
+ }
+ }
+ return true; // Keep iterating through all array items
+ });
+ }
+
+ }
+ return true; // Keep iterating through all dictionary key/value pairs
+ });
+
+ SetThreadStopInfo (tid,
+ expedited_register_map,
+ signo,
+ thread_name,
+ reason,
+ description,
+ exc_type,
+ exc_data,
+ thread_dispatch_qaddr);
+
+ return eStateExited;
+}
StateType
ProcessGDBRemote::SetThreadStopInfo (StringExtractor& stop_packet)
@@ -1825,8 +2182,9 @@ ProcessGDBRemote::SetThreadStopInfo (StringExtractor& stop_packet)
BuildDynamicRegisterInfo (true);
}
// Stop with signal and thread info
+ lldb::tid_t tid = LLDB_INVALID_THREAD_ID;
const uint8_t signo = stop_packet.GetHexU8();
- std::string name;
+ std::string key;
std::string value;
std::string thread_name;
std::string reason;
@@ -1838,48 +2196,25 @@ ProcessGDBRemote::SetThreadStopInfo (StringExtractor& stop_packet)
std::string queue_name;
QueueKind queue_kind = eQueueKindUnknown;
uint64_t queue_serial = 0;
- ThreadSP thread_sp;
- ThreadGDBRemote *gdb_thread = NULL;
-
- while (stop_packet.GetNameColonValue(name, value))
+ ExpeditedRegisterMap expedited_register_map;
+ while (stop_packet.GetNameColonValue(key, value))
{
- if (name.compare("metype") == 0)
+ if (key.compare("metype") == 0)
{
// exception type in big endian hex
exc_type = StringConvert::ToUInt32 (value.c_str(), 0, 16);
}
- else if (name.compare("medata") == 0)
+ else if (key.compare("medata") == 0)
{
// exception data in big endian hex
exc_data.push_back(StringConvert::ToUInt64 (value.c_str(), 0, 16));
}
- else if (name.compare("thread") == 0)
+ else if (key.compare("thread") == 0)
{
// thread in big endian hex
- lldb::tid_t tid = StringConvert::ToUInt64 (value.c_str(), LLDB_INVALID_THREAD_ID, 16);
- // m_thread_list_real does have its own mutex, but we need to
- // hold onto the mutex between the call to m_thread_list_real.FindThreadByID(...)
- // and the m_thread_list_real.AddThread(...) so it doesn't change on us
- Mutex::Locker locker (m_thread_list_real.GetMutex ());
- thread_sp = m_thread_list_real.FindThreadByProtocolID(tid, false);
-
- if (!thread_sp)
- {
- // Create the thread if we need to
- thread_sp.reset (new ThreadGDBRemote (*this, tid));
- Log *log (ProcessGDBRemoteLog::GetLogIfAllCategoriesSet (GDBR_LOG_THREAD));
- if (log && log->GetMask().Test(GDBR_LOG_VERBOSE))
- log->Printf ("ProcessGDBRemote::%s Adding new thread: %p for thread ID: 0x%" PRIx64 ".\n",
- __FUNCTION__,
- static_cast<void*>(thread_sp.get()),
- thread_sp->GetID());
-
- m_thread_list_real.AddThread(thread_sp);
- }
- gdb_thread = static_cast<ThreadGDBRemote *> (thread_sp.get());
-
+ tid = StringConvert::ToUInt64 (value.c_str(), LLDB_INVALID_THREAD_ID, 16);
}
- else if (name.compare("threads") == 0)
+ else if (key.compare("threads") == 0)
{
Mutex::Locker locker(m_thread_list_real.GetMutex());
m_thread_ids.clear();
@@ -1901,7 +2236,7 @@ ProcessGDBRemote::SetThreadStopInfo (StringExtractor& stop_packet)
if (tid != LLDB_INVALID_THREAD_ID)
m_thread_ids.push_back (tid);
}
- else if (name.compare("hexname") == 0)
+ else if (key.compare("hexname") == 0)
{
StringExtractor name_extractor;
// Swap "value" over into "name_extractor"
@@ -1910,15 +2245,15 @@ ProcessGDBRemote::SetThreadStopInfo (StringExtractor& stop_packet)
name_extractor.GetHexByteString (value);
thread_name.swap (value);
}
- else if (name.compare("name") == 0)
+ else if (key.compare("name") == 0)
{
thread_name.swap (value);
}
- else if (name.compare("qaddr") == 0)
+ else if (key.compare("qaddr") == 0)
{
thread_dispatch_qaddr = StringConvert::ToUInt64 (value.c_str(), 0, 16);
}
- else if (name.compare("qname") == 0)
+ else if (key.compare("qname") == 0)
{
queue_vars_valid = true;
StringExtractor name_extractor;
@@ -1928,7 +2263,7 @@ ProcessGDBRemote::SetThreadStopInfo (StringExtractor& stop_packet)
name_extractor.GetHexByteString (value);
queue_name.swap (value);
}
- else if (name.compare("qkind") == 0)
+ else if (key.compare("qkind") == 0)
{
queue_vars_valid = true;
if (value == "serial")
@@ -1936,16 +2271,16 @@ ProcessGDBRemote::SetThreadStopInfo (StringExtractor& stop_packet)
else if (value == "concurrent")
queue_kind = eQueueKindConcurrent;
}
- else if (name.compare("qserial") == 0)
+ else if (key.compare("qserial") == 0)
{
queue_vars_valid = true;
queue_serial = StringConvert::ToUInt64 (value.c_str(), 0, 0);
}
- else if (name.compare("reason") == 0)
+ else if (key.compare("reason") == 0)
{
reason.swap(value);
}
- else if (name.compare("description") == 0)
+ else if (key.compare("description") == 0)
{
StringExtractor desc_extractor;
// Swap "value" over into "name_extractor"
@@ -1954,34 +2289,57 @@ ProcessGDBRemote::SetThreadStopInfo (StringExtractor& stop_packet)
desc_extractor.GetHexByteString (value);
description.swap(value);
}
- else if (name.size() == 2 && ::isxdigit(name[0]) && ::isxdigit(name[1]))
+ else if (key.compare("memory") == 0)
{
- // We have a register number that contains an expedited
- // register value. Lets supply this register to our thread
- // so it won't have to go and read it.
- if (gdb_thread)
+ // Expedited memory. GDB servers can choose to send back expedited memory
+ // that can populate the L1 memory cache in the process so that things like
+ // the frame pointer backchain can be expedited. This will help stack
+ // backtracing be more efficient by not having to send as many memory read
+ // requests down the remote GDB server.
+
+ // Key/value pair format: memory:<addr>=<bytes>;
+ // <addr> is a number whose base will be interpreted by the prefix:
+ // "0x[0-9a-fA-F]+" for hex
+ // "0[0-7]+" for octal
+ // "[1-9]+" for decimal
+ // <bytes> is native endian ASCII hex bytes just like the register values
+ llvm::StringRef value_ref(value);
+ std::pair<llvm::StringRef, llvm::StringRef> pair;
+ pair = value_ref.split('=');
+ if (!pair.first.empty() && !pair.second.empty())
{
- uint32_t reg = StringConvert::ToUInt32 (name.c_str(), UINT32_MAX, 16);
-
- if (reg != UINT32_MAX)
+ std::string addr_str(pair.first.str());
+ const lldb::addr_t mem_cache_addr = StringConvert::ToUInt64(addr_str.c_str(), LLDB_INVALID_ADDRESS, 0);
+ if (mem_cache_addr != LLDB_INVALID_ADDRESS)
{
- StringExtractor reg_value_extractor;
- // Swap "value" over into "reg_value_extractor"
- reg_value_extractor.GetStringRef().swap(value);
- if (!gdb_thread->PrivateSetRegisterValue (reg, reg_value_extractor))
- {
- Host::SetCrashDescriptionWithFormat("Setting thread register '%s' (decoded to %u (0x%x)) with value '%s' for stop packet: '%s'",
- name.c_str(),
- reg,
- reg,
- reg_value_extractor.GetStringRef().c_str(),
- stop_packet.GetStringRef().c_str());
- }
+ StringExtractor bytes;
+ bytes.GetStringRef() = std::move(pair.second.str());
+ const size_t byte_size = bytes.GetStringRef().size()/2;
+ DataBufferSP data_buffer_sp(new DataBufferHeap(byte_size, 0));
+ const size_t bytes_copied = bytes.GetHexBytes (data_buffer_sp->GetBytes(), byte_size, 0);
+ if (bytes_copied == byte_size)
+ m_memory_cache.AddL1CacheData(mem_cache_addr, data_buffer_sp);
}
}
}
+ else if (key.size() == 2 && ::isxdigit(key[0]) && ::isxdigit(key[1]))
+ {
+ uint32_t reg = StringConvert::ToUInt32 (key.c_str(), UINT32_MAX, 16);
+ if (reg != UINT32_MAX)
+ expedited_register_map[reg] = std::move(value);
+ }
}
+ ThreadSP thread_sp = SetThreadStopInfo (tid,
+ expedited_register_map,
+ signo,
+ thread_name,
+ reason,
+ description,
+ exc_type,
+ exc_data,
+ thread_dispatch_qaddr);
+
// If the response is old style 'S' packet which does not provide us with thread information
// then update the thread list and choose the first one.
if (!thread_sp)
@@ -1992,164 +2350,9 @@ ProcessGDBRemote::SetThreadStopInfo (StringExtractor& stop_packet)
{
Mutex::Locker locker (m_thread_list_real.GetMutex ());
thread_sp = m_thread_list_real.FindThreadByProtocolID (m_thread_ids.front (), false);
- if (thread_sp)
- gdb_thread = static_cast<ThreadGDBRemote *> (thread_sp.get ());
}
}
- if (thread_sp)
- {
- // Clear the stop info just in case we don't set it to anything
- thread_sp->SetStopInfo (StopInfoSP());
-
- gdb_thread->SetThreadDispatchQAddr (thread_dispatch_qaddr);
- if (queue_vars_valid)
- gdb_thread->SetQueueInfo(std::move(queue_name), queue_kind, queue_serial);
- else
- gdb_thread->ClearQueueInfo();
-
- gdb_thread->SetName (thread_name.empty() ? NULL : thread_name.c_str());
- if (exc_type != 0)
- {
- const size_t exc_data_size = exc_data.size();
-
- thread_sp->SetStopInfo (StopInfoMachException::CreateStopReasonWithMachException (*thread_sp,
- exc_type,
- exc_data_size,
- exc_data_size >= 1 ? exc_data[0] : 0,
- exc_data_size >= 2 ? exc_data[1] : 0,
- exc_data_size >= 3 ? exc_data[2] : 0));
- }
- else
- {
- bool handled = false;
- bool did_exec = false;
- if (!reason.empty())
- {
- if (reason.compare("trace") == 0)
- {
- thread_sp->SetStopInfo (StopInfo::CreateStopReasonToTrace (*thread_sp));
- handled = true;
- }
- else if (reason.compare("breakpoint") == 0)
- {
- addr_t pc = thread_sp->GetRegisterContext()->GetPC();
- lldb::BreakpointSiteSP bp_site_sp = thread_sp->GetProcess()->GetBreakpointSiteList().FindByAddress(pc);
- if (bp_site_sp)
- {
- // If the breakpoint is for this thread, then we'll report the hit, but if it is for another thread,
- // we can just report no reason. We don't need to worry about stepping over the breakpoint here, that
- // will be taken care of when the thread resumes and notices that there's a breakpoint under the pc.
- handled = true;
- if (bp_site_sp->ValidForThisThread (thread_sp.get()))
- {
- thread_sp->SetStopInfo (StopInfo::CreateStopReasonWithBreakpointSiteID (*thread_sp, bp_site_sp->GetID()));
- }
- else
- {
- StopInfoSP invalid_stop_info_sp;
- thread_sp->SetStopInfo (invalid_stop_info_sp);
- }
- }
- }
- else if (reason.compare("trap") == 0)
- {
- // Let the trap just use the standard signal stop reason below...
- }
- else if (reason.compare("watchpoint") == 0)
- {
- StringExtractor desc_extractor(description.c_str());
- addr_t wp_addr = desc_extractor.GetU64(LLDB_INVALID_ADDRESS);
- uint32_t wp_index = desc_extractor.GetU32(LLDB_INVALID_INDEX32);
- watch_id_t watch_id = LLDB_INVALID_WATCH_ID;
- if (wp_addr != LLDB_INVALID_ADDRESS)
- {
- WatchpointSP wp_sp = GetTarget().GetWatchpointList().FindByAddress(wp_addr);
- if (wp_sp)
- {
- wp_sp->SetHardwareIndex(wp_index);
- watch_id = wp_sp->GetID();
- }
- }
- if (watch_id == LLDB_INVALID_WATCH_ID)
- {
- Log *log (ProcessGDBRemoteLog::GetLogIfAllCategoriesSet (GDBR_LOG_WATCHPOINTS));
- if (log) log->Printf ("failed to find watchpoint");
- }
- thread_sp->SetStopInfo (StopInfo::CreateStopReasonWithWatchpointID (*thread_sp, watch_id));
- handled = true;
- }
- else if (reason.compare("exception") == 0)
- {
- thread_sp->SetStopInfo (StopInfo::CreateStopReasonWithException(*thread_sp, description.c_str()));
- handled = true;
- }
- else if (reason.compare("exec") == 0)
- {
- did_exec = true;
- thread_sp->SetStopInfo (StopInfo::CreateStopReasonWithExec(*thread_sp));
- handled = true;
- }
- }
-
- if (!handled && signo && did_exec == false)
- {
- if (signo == SIGTRAP)
- {
- // Currently we are going to assume SIGTRAP means we are either
- // hitting a breakpoint or hardware single stepping.
- handled = true;
- addr_t pc = thread_sp->GetRegisterContext()->GetPC() + m_breakpoint_pc_offset;
- lldb::BreakpointSiteSP bp_site_sp = thread_sp->GetProcess()->GetBreakpointSiteList().FindByAddress(pc);
-
- if (bp_site_sp)
- {
- // If the breakpoint is for this thread, then we'll report the hit, but if it is for another thread,
- // we can just report no reason. We don't need to worry about stepping over the breakpoint here, that
- // will be taken care of when the thread resumes and notices that there's a breakpoint under the pc.
- if (bp_site_sp->ValidForThisThread (thread_sp.get()))
- {
- if(m_breakpoint_pc_offset != 0)
- thread_sp->GetRegisterContext()->SetPC(pc);
- thread_sp->SetStopInfo (StopInfo::CreateStopReasonWithBreakpointSiteID (*thread_sp, bp_site_sp->GetID()));
- }
- else
- {
- StopInfoSP invalid_stop_info_sp;
- thread_sp->SetStopInfo (invalid_stop_info_sp);
- }
- }
- else
- {
- // If we were stepping then assume the stop was the result of the trace. If we were
- // not stepping then report the SIGTRAP.
- // FIXME: We are still missing the case where we single step over a trap instruction.
- if (thread_sp->GetTemporaryResumeState() == eStateStepping)
- thread_sp->SetStopInfo (StopInfo::CreateStopReasonToTrace (*thread_sp));
- else
- thread_sp->SetStopInfo (StopInfo::CreateStopReasonWithSignal(*thread_sp, signo, description.c_str()));
- }
- }
- if (!handled)
- thread_sp->SetStopInfo (StopInfo::CreateStopReasonWithSignal (*thread_sp, signo, description.c_str()));
- }
-
- if (!description.empty())
- {
- lldb::StopInfoSP stop_info_sp (thread_sp->GetStopInfo ());
- if (stop_info_sp)
- {
- const char *stop_info_desc = stop_info_sp->GetDescription();
- if (!stop_info_desc || !stop_info_desc[0])
- stop_info_sp->SetDescription (description.c_str());
- }
- else
- {
- thread_sp->SetStopInfo (StopInfo::CreateStopReasonWithException (*thread_sp, description.c_str()));
- }
- }
- }
- }
return eStateStopped;
}
break;
@@ -2206,6 +2409,11 @@ ProcessGDBRemote::RefreshStateAfterStop ()
m_initial_tid = LLDB_INVALID_THREAD_ID;
}
+ // Fetch the threads via an efficient packet that gets stop infos for all threads
+ // only if we have more than one thread
+ if (m_thread_ids.size() > 1)
+ m_threads_info_sp = m_gdb_comm.GetThreadsInfo();
+
// Let all threads recover from stopping and do any clean up based
// on the previous thread state (if any).
m_thread_list_real.RefreshStateAfterStop();
diff --git a/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h b/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h
index 16e47dfcba6..d810d9ce2f1 100644
--- a/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h
+++ b/lldb/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h
@@ -326,6 +326,9 @@ protected:
void
GetMaxMemorySize();
+ bool
+ CalculateThreadStopInfo (ThreadGDBRemote *thread);
+
//------------------------------------------------------------------
/// Broadcaster event bits definitions.
//------------------------------------------------------------------
@@ -348,7 +351,9 @@ protected:
typedef std::vector<lldb::tid_t> tid_collection;
typedef std::vector< std::pair<lldb::tid_t,int> > tid_sig_collection;
typedef std::map<lldb::addr_t, lldb::addr_t> MMapMap;
+ typedef std::map<uint32_t, std::string> ExpeditedRegisterMap;
tid_collection m_thread_ids; // Thread IDs for all threads. This list gets updated after stopping
+ StructuredData::ObjectSP m_threads_info_sp; // Stop info for all threads if "jThreadsInfo" packet is supported
tid_collection m_continue_c_tids; // 'c' for continue
tid_sig_collection m_continue_C_tids; // 'C' for continue with signal
tid_collection m_continue_s_tids; // 's' for step
@@ -385,6 +390,20 @@ protected:
lldb::StateType
SetThreadStopInfo (StringExtractor& stop_packet);
+ lldb::StateType
+ SetThreadStopInfo (StructuredData::Dictionary *thread_dict);
+
+ lldb::ThreadSP
+ SetThreadStopInfo (lldb::tid_t tid,
+ ExpeditedRegisterMap &expedited_register_map,
+ uint8_t signo,
+ const std::string &thread_name,
+ const std::string &reason,
+ const std::string &description,
+ uint32_t exc_type,
+ const std::vector<lldb::addr_t> &exc_data,
+ lldb::addr_t thread_dispatch_qaddr);
+
void
HandleStopReplySequence ();
diff --git a/lldb/source/Plugins/Process/gdb-remote/ThreadGDBRemote.cpp b/lldb/source/Plugins/Process/gdb-remote/ThreadGDBRemote.cpp
index e58121b1978..59c701d75a6 100644
--- a/lldb/source/Plugins/Process/gdb-remote/ThreadGDBRemote.cpp
+++ b/lldb/source/Plugins/Process/gdb-remote/ThreadGDBRemote.cpp
@@ -317,12 +317,7 @@ ThreadGDBRemote::CalculateStopInfo ()
{
ProcessSP process_sp (GetProcess());
if (process_sp)
- {
- StringExtractorGDBRemote stop_packet;
- ProcessGDBRemote *gdb_process = static_cast<ProcessGDBRemote *>(process_sp.get());
- if (gdb_process->GetGDBRemote().GetThreadStopInfo(GetProtocolID(), stop_packet))
- return gdb_process->SetThreadStopInfo (stop_packet) == eStateStopped;
- }
+ return static_cast<ProcessGDBRemote *>(process_sp.get())->CalculateThreadStopInfo(this);
return false;
}
diff --git a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
index 4d3d22a6211..dafd389449a 100644
--- a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
+++ b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
@@ -7620,7 +7620,7 @@ SymbolFileDWARF::ParseVariableDIE
{
if (exe_symbol->ValueIsAddress())
{
- const addr_t exe_file_addr = exe_symbol->GetAddress().GetFileAddress();
+ const addr_t exe_file_addr = exe_symbol->GetAddressRef().GetFileAddress();
if (exe_file_addr != LLDB_INVALID_ADDRESS)
{
if (location.Update_DW_OP_addr (exe_file_addr))
diff --git a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.cpp b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.cpp
index d5d60aed03e..5579a23ce71 100644
--- a/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.cpp
+++ b/lldb/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.cpp
@@ -121,8 +121,8 @@ SymbolFileDWARFDebugMap::CompileUnitInfo::GetFileRangeMap(SymbolFileDWARFDebugMa
{
// Add the inverse OSO file address to debug map entry mapping
exe_symfile->AddOSOFileRange (this,
- exe_symbol->GetAddress().GetFileAddress(),
- oso_fun_symbol->GetAddress().GetFileAddress(),
+ exe_symbol->GetAddressRef().GetFileAddress(),
+ oso_fun_symbol->GetAddressRef().GetFileAddress(),
std::min<addr_t>(exe_symbol->GetByteSize(), oso_fun_symbol->GetByteSize()));
}
@@ -155,8 +155,8 @@ SymbolFileDWARFDebugMap::CompileUnitInfo::GetFileRangeMap(SymbolFileDWARFDebugMa
{
// Add the inverse OSO file address to debug map entry mapping
exe_symfile->AddOSOFileRange (this,
- exe_symbol->GetAddress().GetFileAddress(),
- oso_gsym_symbol->GetAddress().GetFileAddress(),
+ exe_symbol->GetAddressRef().GetFileAddress(),
+ oso_gsym_symbol->GetAddressRef().GetFileAddress(),
std::min<addr_t>(exe_symbol->GetByteSize(), oso_gsym_symbol->GetByteSize()));
}
}
@@ -374,7 +374,7 @@ SymbolFileDWARFDebugMap::InitOSO()
for (uint32_t sym_idx : m_func_indexes)
{
const Symbol *symbol = symtab->SymbolAtIndex(sym_idx);
- lldb::addr_t file_addr = symbol->GetAddress().GetFileAddress();
+ lldb::addr_t file_addr = symbol->GetAddressRef().GetFileAddress();
lldb::addr_t byte_size = symbol->GetByteSize();
DebugMap::Entry debug_map_entry(file_addr, byte_size, OSOEntry(sym_idx, LLDB_INVALID_ADDRESS));
m_debug_map.Append(debug_map_entry);
@@ -382,7 +382,7 @@ SymbolFileDWARFDebugMap::InitOSO()
for (uint32_t sym_idx : m_glob_indexes)
{
const Symbol *symbol = symtab->SymbolAtIndex(sym_idx);
- lldb::addr_t file_addr = symbol->GetAddress().GetFileAddress();
+ lldb::addr_t file_addr = symbol->GetAddressRef().GetFileAddress();
lldb::addr_t byte_size = symbol->GetByteSize();
DebugMap::Entry debug_map_entry(file_addr, byte_size, OSOEntry(sym_idx, LLDB_INVALID_ADDRESS));
m_debug_map.Append(debug_map_entry);
@@ -405,7 +405,7 @@ SymbolFileDWARFDebugMap::InitOSO()
m_compile_unit_infos[i].so_file.SetFile(so_symbol->GetName().AsCString(), false);
m_compile_unit_infos[i].oso_path = oso_symbol->GetName();
TimeValue oso_mod_time;
- oso_mod_time.OffsetWithSeconds(oso_symbol->GetAddress().GetOffset());
+ oso_mod_time.OffsetWithSeconds(oso_symbol->GetIntegerValue(0));
m_compile_unit_infos[i].oso_mod_time = oso_mod_time;
uint32_t sibling_idx = so_symbol->GetSiblingIndex();
// The sibling index can't be less that or equal to the current index "i"
diff --git a/lldb/source/Plugins/SymbolFile/Symtab/SymbolFileSymtab.cpp b/lldb/source/Plugins/SymbolFile/Symtab/SymbolFileSymtab.cpp
index 8eb3e3a09c8..64c88ab716b 100644
--- a/lldb/source/Plugins/SymbolFile/Symtab/SymbolFileSymtab.cpp
+++ b/lldb/source/Plugins/SymbolFile/Symtab/SymbolFileSymtab.cpp
@@ -225,7 +225,7 @@ SymbolFileSymtab::ParseCompileUnitFunctions (const SymbolContext &sc)
next_symbol = symtab->SymbolAtIndex(m_code_indexes[idx + 1]);
if (next_symbol)
{
- func_range.SetByteSize(next_symbol->GetAddress().GetOffset() - curr_symbol->GetAddress().GetOffset());
+ func_range.SetByteSize(next_symbol->GetAddressRef().GetOffset() - curr_symbol->GetAddressRef().GetOffset());
}
}
diff --git a/lldb/source/Plugins/SystemRuntime/MacOSX/SystemRuntimeMacOSX.cpp b/lldb/source/Plugins/SystemRuntime/MacOSX/SystemRuntimeMacOSX.cpp
index 9b18eadbf1d..67f9c59cadf 100644
--- a/lldb/source/Plugins/SystemRuntime/MacOSX/SystemRuntimeMacOSX.cpp
+++ b/lldb/source/Plugins/SystemRuntime/MacOSX/SystemRuntimeMacOSX.cpp
@@ -316,7 +316,7 @@ SystemRuntimeMacOSX::ReadLibdispatchOffsetsAddress ()
dispatch_queue_offsets_symbol = module_sp->FindFirstSymbolWithNameAndType (g_dispatch_queue_offsets_symbol_name, eSymbolTypeData);
}
if (dispatch_queue_offsets_symbol)
- m_dispatch_queue_offsets_addr = dispatch_queue_offsets_symbol->GetAddress().GetLoadAddress(&m_process->GetTarget());
+ m_dispatch_queue_offsets_addr = dispatch_queue_offsets_symbol->GetLoadAddress(&m_process->GetTarget());
}
void
@@ -361,7 +361,7 @@ SystemRuntimeMacOSX::ReadLibpthreadOffsetsAddress ()
(g_libpthread_layout_offsets_symbol_name, eSymbolTypeData);
if (libpthread_layout_offsets_symbol)
{
- m_libpthread_layout_offsets_addr = libpthread_layout_offsets_symbol->GetAddress().GetLoadAddress(&m_process->GetTarget());
+ m_libpthread_layout_offsets_addr = libpthread_layout_offsets_symbol->GetLoadAddress(&m_process->GetTarget());
}
}
}
@@ -410,7 +410,7 @@ SystemRuntimeMacOSX::ReadLibdispatchTSDIndexesAddress ()
(g_libdispatch_tsd_indexes_symbol_name, eSymbolTypeData);
if (libdispatch_tsd_indexes_symbol)
{
- m_dispatch_tsd_indexes_addr = libdispatch_tsd_indexes_symbol->GetAddress().GetLoadAddress(&m_process->GetTarget());
+ m_dispatch_tsd_indexes_addr = libdispatch_tsd_indexes_symbol->GetLoadAddress(&m_process->GetTarget());
}
}
}
diff --git a/lldb/source/Symbol/ObjectFile.cpp b/lldb/source/Symbol/ObjectFile.cpp
index b860bcfce56..22a313cf6a2 100644
--- a/lldb/source/Symbol/ObjectFile.cpp
+++ b/lldb/source/Symbol/ObjectFile.cpp
@@ -328,7 +328,7 @@ ObjectFile::GetAddressClass (addr_t file_addr)
{
if (symbol->ValueIsAddress())
{
- const SectionSP section_sp (symbol->GetAddress().GetSection());
+ const SectionSP section_sp (symbol->GetAddressRef().GetSection());
if (section_sp)
{
const SectionType section_type = section_sp->GetType();
diff --git a/lldb/source/Symbol/Symbol.cpp b/lldb/source/Symbol/Symbol.cpp
index 4a1ae8197b8..dff15dd9261 100644
--- a/lldb/source/Symbol/Symbol.cpp
+++ b/lldb/source/Symbol/Symbol.cpp
@@ -491,7 +491,7 @@ Symbol::CalculateSymbolContext (SymbolContext *sc)
// Symbols can reconstruct the symbol and the module in the symbol context
sc->symbol = this;
if (ValueIsAddress())
- sc->module_sp = GetAddress().GetModule();
+ sc->module_sp = GetAddressRef().GetModule();
else
sc->module_sp.reset();
}
@@ -500,7 +500,7 @@ ModuleSP
Symbol::CalculateSymbolContextModule ()
{
if (ValueIsAddress())
- return GetAddress().GetModule();
+ return GetAddressRef().GetModule();
return ModuleSP();
}
@@ -516,7 +516,7 @@ Symbol::DumpSymbolContext (Stream *s)
bool dumped_module = false;
if (ValueIsAddress())
{
- ModuleSP module_sp (GetAddress().GetModule());
+ ModuleSP module_sp (GetAddressRef().GetModule());
if (module_sp)
{
dumped_module = true;
@@ -618,6 +618,25 @@ Symbol::ResolveReExportedSymbol (Target &target) const
}
lldb::addr_t
+Symbol::GetFileAddress () const
+{
+ if (ValueIsAddress())
+ return GetAddressRef().GetFileAddress();
+ else
+ return LLDB_INVALID_ADDRESS;
+}
+
+lldb::addr_t
+Symbol::GetLoadAddress (Target *target) const
+{
+ if (ValueIsAddress())
+ return GetAddressRef().GetLoadAddress(target);
+ else
+ return LLDB_INVALID_ADDRESS;
+}
+
+
+lldb::addr_t
Symbol::ResolveCallableAddress(Target &target) const
{
if (GetType() == lldb::eSymbolTypeUndefined)
diff --git a/lldb/source/Symbol/SymbolContext.cpp b/lldb/source/Symbol/SymbolContext.cpp
index d65462be526..8e4240a4587 100644
--- a/lldb/source/Symbol/SymbolContext.cpp
+++ b/lldb/source/Symbol/SymbolContext.cpp
@@ -245,7 +245,7 @@ SymbolContext::DumpStopContext (
if (addr.IsValid() && symbol->ValueIsAddress())
{
- const addr_t symbol_offset = addr.GetOffset() - symbol->GetAddress().GetOffset();
+ const addr_t symbol_offset = addr.GetOffset() - symbol->GetAddressRef().GetOffset();
if (show_function_name == false)
{
// Print +offset even if offset is 0
@@ -515,7 +515,7 @@ SymbolContext::GetAddressRange (uint32_t scope,
{
if (symbol->ValueIsAddress())
{
- range.GetBaseAddress() = symbol->GetAddress();
+ range.GetBaseAddress() = symbol->GetAddressRef();
range.SetByteSize (symbol->GetByteSize());
return true;
}
@@ -1106,7 +1106,7 @@ SymbolContextList::AppendIfUnique (const SymbolContext& sc, bool merge_symbol_in
if (pos->function)
{
- if (pos->function->GetAddressRange().GetBaseAddress() == sc.symbol->GetAddress())
+ if (pos->function->GetAddressRange().GetBaseAddress() == sc.symbol->GetAddressRef())
{
// Do we already have a function with this symbol?
if (pos->symbol == sc.symbol)
@@ -1148,7 +1148,7 @@ SymbolContextList::MergeSymbolContextIntoFunctionContext (const SymbolContext& s
if (function_sc.function)
{
- if (function_sc.function->GetAddressRange().GetBaseAddress() == symbol_sc.symbol->GetAddress())
+ if (function_sc.function->GetAddressRange().GetBaseAddress() == symbol_sc.symbol->GetAddressRef())
{
// Do we already have a function with this symbol?
if (function_sc.symbol == symbol_sc.symbol)
diff --git a/lldb/source/Symbol/Symtab.cpp b/lldb/source/Symbol/Symtab.cpp
index dc695258baf..4cc03345d05 100644
--- a/lldb/source/Symbol/Symtab.cpp
+++ b/lldb/source/Symbol/Symtab.cpp
@@ -598,14 +598,14 @@ namespace {
addr_t value_a = addr_cache[index_a];
if (value_a == LLDB_INVALID_ADDRESS)
{
- value_a = symbols[index_a].GetAddress().GetFileAddress();
+ value_a = symbols[index_a].GetAddressRef().GetFileAddress();
addr_cache[index_a] = value_a;
}
addr_t value_b = addr_cache[index_b];
if (value_b == LLDB_INVALID_ADDRESS)
{
- value_b = symbols[index_b].GetAddress().GetFileAddress();
+ value_b = symbols[index_b].GetAddressRef().GetFileAddress();
addr_cache[index_b] = value_b;
}
@@ -902,7 +902,7 @@ SymbolWithClosestFileAddress (SymbolSearchInfo *info, const uint32_t *index_ptr)
const addr_t info_file_addr = info->file_addr;
if (symbol->ValueIsAddress())
{
- const addr_t curr_file_addr = symbol->GetAddress().GetFileAddress();
+ const addr_t curr_file_addr = symbol->GetAddressRef().GetFileAddress();
if (info_file_addr < curr_file_addr)
return -1;
@@ -936,7 +936,7 @@ Symtab::InitAddressIndexes()
{
if (pos->ValueIsAddress())
{
- entry.SetRangeBase(pos->GetAddress().GetFileAddress());
+ entry.SetRangeBase(pos->GetAddressRef().GetFileAddress());
entry.SetByteSize(pos->GetByteSize());
entry.data = std::distance(begin, pos);
m_file_addr_to_index.Append(entry);
diff --git a/lldb/source/Target/Memory.cpp b/lldb/source/Target/Memory.cpp
index 934bc967b68..e61b3ab91e7 100644
--- a/lldb/source/Target/Memory.cpp
+++ b/lldb/source/Target/Memory.cpp
@@ -14,8 +14,9 @@
// Other libraries and framework includes
// Project includes
#include "lldb/Core/DataBufferHeap.h"
-#include "lldb/Core/State.h"
#include "lldb/Core/Log.h"
+#include "lldb/Core/RangeMap.h"
+#include "lldb/Core/State.h"
#include "lldb/Target/Process.h"
using namespace lldb;
@@ -25,11 +26,12 @@ using namespace lldb_private;
// MemoryCache constructor
//----------------------------------------------------------------------
MemoryCache::MemoryCache(Process &process) :
- m_process (process),
- m_cache_line_byte_size (process.GetMemoryCacheLineSize()),
m_mutex (Mutex::eMutexTypeRecursive),
- m_cache (),
- m_invalid_ranges ()
+ m_L1_cache (),
+ m_L2_cache (),
+ m_invalid_ranges (),
+ m_process (process),
+ m_L2_cache_line_byte_size (process.GetMemoryCacheLineSize())
{
}
@@ -44,10 +46,24 @@ void
MemoryCache::Clear(bool clear_invalid_ranges)
{
Mutex::Locker locker (m_mutex);
- m_cache.clear();
+ m_L1_cache.clear();
+ m_L2_cache.clear();
if (clear_invalid_ranges)
m_invalid_ranges.Clear();
- m_cache_line_byte_size = m_process.GetMemoryCacheLineSize();
+ m_L2_cache_line_byte_size = m_process.GetMemoryCacheLineSize();
+}
+
+void
+MemoryCache::AddL1CacheData(lldb::addr_t addr, const void *src, size_t src_len)
+{
+ AddL1CacheData(addr,DataBufferSP (new DataBufferHeap(DataBufferHeap(src, src_len))));
+}
+
+void
+MemoryCache::AddL1CacheData(lldb::addr_t addr, const DataBufferSP &data_buffer_sp)
+{
+ Mutex::Locker locker (m_mutex);
+ m_L1_cache[addr] = data_buffer_sp;
}
void
@@ -57,29 +73,44 @@ MemoryCache::Flush (addr_t addr, size_t size)
return;
Mutex::Locker locker (m_mutex);
- if (m_cache.empty())
- return;
- const uint32_t cache_line_byte_size = m_cache_line_byte_size;
- const addr_t end_addr = (addr + size - 1);
- const addr_t first_cache_line_addr = addr - (addr % cache_line_byte_size);
- const addr_t last_cache_line_addr = end_addr - (end_addr % cache_line_byte_size);
- // Watch for overflow where size will cause us to go off the end of the
- // 64 bit address space
- uint32_t num_cache_lines;
- if (last_cache_line_addr >= first_cache_line_addr)
- num_cache_lines = ((last_cache_line_addr - first_cache_line_addr)/cache_line_byte_size) + 1;
- else
- num_cache_lines = (UINT64_MAX - first_cache_line_addr + 1)/cache_line_byte_size;
-
- uint32_t cache_idx = 0;
- for (addr_t curr_addr = first_cache_line_addr;
- cache_idx < num_cache_lines;
- curr_addr += cache_line_byte_size, ++cache_idx)
+ // Erase any blocks from the L1 cache that intersect with the flush range
+ if (!m_L1_cache.empty())
{
- BlockMap::iterator pos = m_cache.find (curr_addr);
- if (pos != m_cache.end())
- m_cache.erase(pos);
+ AddrRange flush_range(addr, size);
+ BlockMap::iterator pos = m_L1_cache.lower_bound(addr);
+ while (pos != m_L1_cache.end())
+ {
+ AddrRange chunk_range(pos->first, pos->second->GetByteSize());
+ if (!chunk_range.DoesIntersect(flush_range))
+ break;
+ pos = m_L1_cache.erase(pos);
+ }
+ }
+
+ if (!m_L2_cache.empty())
+ {
+ const uint32_t cache_line_byte_size = m_L2_cache_line_byte_size;
+ const addr_t end_addr = (addr + size - 1);
+ const addr_t first_cache_line_addr = addr - (addr % cache_line_byte_size);
+ const addr_t last_cache_line_addr = end_addr - (end_addr % cache_line_byte_size);
+ // Watch for overflow where size will cause us to go off the end of the
+ // 64 bit address space
+ uint32_t num_cache_lines;
+ if (last_cache_line_addr >= first_cache_line_addr)
+ num_cache_lines = ((last_cache_line_addr - first_cache_line_addr)/cache_line_byte_size) + 1;
+ else
+ num_cache_lines = (UINT64_MAX - first_cache_line_addr + 1)/cache_line_byte_size;
+
+ uint32_t cache_idx = 0;
+ for (addr_t curr_addr = first_cache_line_addr;
+ cache_idx < num_cache_lines;
+ curr_addr += cache_line_byte_size, ++cache_idx)
+ {
+ BlockMap::iterator pos = m_L2_cache.find (curr_addr);
+ if (pos != m_L2_cache.end())
+ m_L2_cache.erase(pos);
+ }
}
}
@@ -122,6 +153,39 @@ MemoryCache::Read (addr_t addr,
{
size_t bytes_left = dst_len;
+ // Check the L1 cache for a range that contain the entire memory read.
+ // If we find a range in the L1 cache that does, we use it. Else we fall
+ // back to reading memory in m_L2_cache_line_byte_size byte sized chunks.
+ // The L1 cache contains chunks of memory that are not required to be
+ // m_L2_cache_line_byte_size bytes in size, so we don't try anything
+ // tricky when reading from them (no partial reads from the L1 cache).
+
+ Mutex::Locker locker(m_mutex);
+ if (!m_L1_cache.empty())
+ {
+ AddrRange read_range(addr, dst_len);
+ BlockMap::iterator pos = m_L1_cache.lower_bound(addr);
+ if (pos != m_L1_cache.end())
+ {
+ AddrRange chunk_range(pos->first, pos->second->GetByteSize());
+ bool match = chunk_range.Contains(read_range);
+ if (!match && pos != m_L1_cache.begin())
+ {
+ --pos;
+ chunk_range.SetRangeBase(pos->first);
+ chunk_range.SetByteSize(pos->second->GetByteSize());
+ match = chunk_range.Contains(read_range);
+ }
+
+ if (match)
+ {
+ memcpy(dst, pos->second->GetBytes() + addr - chunk_range.GetRangeBase(), dst_len);
+ return dst_len;
+ }
+ }
+ }
+
+
// If this memory read request is larger than the cache line size, then
// we (1) try to read as much of it at once as possible, and (2) don't
// add the data to the memory cache. We don't want to split a big read
@@ -129,19 +193,22 @@ MemoryCache::Read (addr_t addr,
// request, it is unlikely that the caller function will ask for the next
// 4 bytes after the large memory read - so there's little benefit to saving
// it in the cache.
- if (dst && dst_len > m_cache_line_byte_size)
+ if (dst && dst_len > m_L2_cache_line_byte_size)
{
- return m_process.ReadMemoryFromInferior (addr, dst, dst_len, error);
+ size_t bytes_read = m_process.ReadMemoryFromInferior (addr, dst, dst_len, error);
+ // Add this non block sized range to the L1 cache if we actually read anything
+ if (bytes_read > 0)
+ AddL1CacheData(addr, dst, bytes_read);
+ return bytes_read;
}
if (dst && bytes_left > 0)
{
- const uint32_t cache_line_byte_size = m_cache_line_byte_size;
+ const uint32_t cache_line_byte_size = m_L2_cache_line_byte_size;
uint8_t *dst_buf = (uint8_t *)dst;
addr_t curr_addr = addr - (addr % cache_line_byte_size);
addr_t cache_offset = addr - curr_addr;
- Mutex::Locker locker (m_mutex);
-
+
while (bytes_left > 0)
{
if (m_invalid_ranges.FindEntryThatContains(curr_addr))
@@ -150,8 +217,8 @@ MemoryCache::Read (addr_t addr,
return dst_len - bytes_left;
}
- BlockMap::const_iterator pos = m_cache.find (curr_addr);
- BlockMap::const_iterator end = m_cache.end ();
+ BlockMap::const_iterator pos = m_L2_cache.find (curr_addr);
+ BlockMap::const_iterator end = m_L2_cache.end ();
if (pos != end)
{
@@ -208,7 +275,7 @@ MemoryCache::Read (addr_t addr,
if (process_bytes_read != cache_line_byte_size)
data_buffer_heap_ap->SetByteSize (process_bytes_read);
- m_cache[curr_addr] = DataBufferSP (data_buffer_heap_ap.release());
+ m_L2_cache[curr_addr] = DataBufferSP (data_buffer_heap_ap.release());
// We have read data and put it into the cache, continue through the
// loop again to get the data out of the cache...
}
diff --git a/lldb/source/Target/Process.cpp b/lldb/source/Target/Process.cpp
index 77e9b5dbc0a..41942829ca5 100644
--- a/lldb/source/Target/Process.cpp
+++ b/lldb/source/Target/Process.cpp
@@ -2246,11 +2246,12 @@ Process::CreateBreakpointSite (const BreakpointLocationSP &owner, bool use_hardw
if (symbol && symbol->IsIndirect())
{
Error error;
- load_addr = ResolveIndirectFunction (&symbol->GetAddress(), error);
+ Address symbol_address = symbol->GetAddress();
+ load_addr = ResolveIndirectFunction (&symbol_address, error);
if (!error.Success() && show_error)
{
m_target.GetDebugger().GetErrorFile()->Printf ("warning: failed to resolve indirect function at 0x%" PRIx64 " for breakpoint %i.%i: %s\n",
- symbol->GetAddress().GetLoadAddress(&m_target),
+ symbol->GetLoadAddress(&m_target),
owner->GetBreakpoint().GetID(),
owner->GetID(),
error.AsCString() ? error.AsCString() : "unknown error");
diff --git a/lldb/source/Target/ThreadPlanStepRange.cpp b/lldb/source/Target/ThreadPlanStepRange.cpp
index 324f5a7c653..3aed8585950 100644
--- a/lldb/source/Target/ThreadPlanStepRange.cpp
+++ b/lldb/source/Target/ThreadPlanStepRange.cpp
@@ -243,9 +243,9 @@ ThreadPlanStepRange::InSymbol()
{
return m_addr_context.function->GetAddressRange().ContainsLoadAddress (cur_pc, m_thread.CalculateTarget().get());
}
- else if (m_addr_context.symbol)
+ else if (m_addr_context.symbol && m_addr_context.symbol->ValueIsAddress())
{
- AddressRange range(m_addr_context.symbol->GetAddress(), m_addr_context.symbol->GetByteSize());
+ AddressRange range(m_addr_context.symbol->GetAddressRef(), m_addr_context.symbol->GetByteSize());
return range.ContainsLoadAddress (cur_pc, m_thread.CalculateTarget().get());
}
return false;
diff --git a/lldb/tools/debugserver/debugserver.xcodeproj/project.pbxproj b/lldb/tools/debugserver/debugserver.xcodeproj/project.pbxproj
index f7cbc1338fb..c82421238af 100644
--- a/lldb/tools/debugserver/debugserver.xcodeproj/project.pbxproj
+++ b/lldb/tools/debugserver/debugserver.xcodeproj/project.pbxproj
@@ -55,6 +55,7 @@
26203D1D1641EFB200A662F7 /* com.apple.debugserver.internal.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = com.apple.debugserver.internal.plist; sourceTree = "<group>"; };
26242C390DDBD33C0054A4CC /* debugserver-entitlements.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = "debugserver-entitlements.plist"; sourceTree = "<group>"; };
264D5D571293835600ED4C01 /* DNBArch.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = DNBArch.cpp; sourceTree = "<group>"; };
+ 264F679A1B2F9EB200140093 /* JSONGenerator.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = JSONGenerator.h; sourceTree = "<group>"; };
26593A060D4931CC001C9FE3 /* ChangeLog */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = ChangeLog; sourceTree = "<group>"; };
2660D9CC1192280900958FBD /* StringExtractor.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = StringExtractor.cpp; path = ../../source/Utility/StringExtractor.cpp; sourceTree = SOURCE_ROOT; };
2660D9CD1192280900958FBD /* StringExtractor.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = StringExtractor.h; path = ../../source/Utility/StringExtractor.h; sourceTree = SOURCE_ROOT; };
@@ -232,6 +233,7 @@
26C637E20C71334A0024798E /* DNBRegisterInfo.cpp */,
260E7332114BFFE600D1DFB3 /* DNBThreadResumeActions.h */,
260E7331114BFFE600D1DFB3 /* DNBThreadResumeActions.cpp */,
+ 264F679A1B2F9EB200140093 /* JSONGenerator.h */,
AF67AC000D34604D0022D128 /* PseudoTerminal.h */,
AF67ABFF0D34604D0022D128 /* PseudoTerminal.cpp */,
26C637FD0C71334A0024798E /* PThreadCondition.h */,
diff --git a/lldb/tools/debugserver/source/RNBRemote.cpp b/lldb/tools/debugserver/source/RNBRemote.cpp
index 1ddf9027427..7498f2ea907 100644
--- a/lldb/tools/debugserver/source/RNBRemote.cpp
+++ b/lldb/tools/debugserver/source/RNBRemote.cpp
@@ -29,6 +29,7 @@
#include "DNBDataRef.h"
#include "DNBLog.h"
#include "DNBThreadResumeActions.h"
+#include "JSONGenerator.h"
#include "RNBContext.h"
#include "RNBServices.h"
#include "RNBSocket.h"
@@ -262,6 +263,7 @@ RNBRemote::CreatePacketTable ()
t.push_back (Packet (query_process_info, &RNBRemote::HandlePacket_qProcessInfo , NULL, "qProcessInfo", "Replies with multiple 'key:value;' tuples appended to each other."));
t.push_back (Packet (query_symbol_lookup, &RNBRemote::HandlePacket_qSymbol , NULL, "qSymbol:", "Notify that host debugger is ready to do symbol lookups"));
t.push_back (Packet (json_query_thread_extended_info,&RNBRemote::HandlePacket_jThreadExtendedInfo , NULL, "jThreadExtendedInfo", "Replies with JSON data of thread extended information."));
+ //t.push_back (Packet (json_query_threads_info, &RNBRemote::HandlePacket_jThreadsInfo , NULL, "jThreadsInfo", "Replies with JSON data with information about all threads."));
t.push_back (Packet (start_noack_mode, &RNBRemote::HandlePacket_QStartNoAckMode , NULL, "QStartNoAckMode", "Request that " DEBUGSERVER_PROGRAM_NAME " stop acking remote protocol packets"));
t.push_back (Packet (prefix_reg_packets_with_tid, &RNBRemote::HandlePacket_QThreadSuffixSupported , NULL, "QThreadSuffixSupported", "Check if thread specific packets (register packets 'g', 'G', 'p', and 'P') support having the thread ID appended to the end of the command"));
t.push_back (Packet (set_logging_mode, &RNBRemote::HandlePacket_QSetLogging , NULL, "QSetLogging:", "Check if register packets ('g', 'G', 'p', and 'P' support having the thread ID prefix"));
@@ -2559,6 +2561,52 @@ RNBRemote::DispatchQueueOffsets::GetThreadQueueInfo (nub_process_t pid,
}
}
+struct StackMemory
+{
+ uint8_t bytes[2*sizeof(nub_addr_t)];
+ nub_size_t length;
+};
+typedef std::map<nub_addr_t, StackMemory> StackMemoryMap;
+
+
+static void
+ReadStackMemory (nub_process_t pid, nub_thread_t tid, StackMemoryMap &stack_mmap)
+{
+ DNBRegisterValue reg_value;
+ if (DNBThreadGetRegisterValueByID(pid, tid, REGISTER_SET_GENERIC, GENERIC_REGNUM_FP, &reg_value))
+ {
+ uint32_t frame_count = 0;
+ uint64_t fp = 0;
+ if (reg_value.info.size == 4)
+ fp = reg_value.value.uint32;
+ else
+ fp = reg_value.value.uint64;
+ while (fp != 0)
+ {
+ // Make sure we never recurse more than 256 times so we don't recurse too far or
+ // store up too much memory in the expedited cache
+ if (++frame_count > 256)
+ break;
+
+ const nub_size_t read_size = reg_value.info.size*2;
+ StackMemory stack_memory;
+ stack_memory.length = read_size;
+ if (DNBProcessMemoryRead(pid, fp, read_size, stack_memory.bytes) != read_size)
+ break;
+ // Make sure we don't try to put the same stack memory in more than once
+ if (stack_mmap.find(fp) != stack_mmap.end())
+ break;
+ // Put the entry into the cache
+ stack_mmap[fp] = stack_memory;
+ // Dereference the frame pointer to get to the previous frame pointer
+ if (reg_value.info.size == 4)
+ fp = ((uint32_t *)stack_memory.bytes)[0];
+ else
+ fp = ((uint64_t *)stack_memory.bytes)[0];
+ }
+ }
+}
+
rnb_err_t
RNBRemote::SendStopReplyPacketForThread (nub_thread_t tid)
{
@@ -2714,11 +2762,26 @@ RNBRemote::SendStopReplyPacketForThread (nub_thread_t tid)
}
else if (tid_stop_info.details.exception.type)
{
- ostrm << "metype:" << std::hex << tid_stop_info.details.exception.type << ";";
- ostrm << "mecount:" << std::hex << tid_stop_info.details.exception.data_count << ";";
+ ostrm << "metype:" << std::hex << tid_stop_info.details.exception.type << ';';
+ ostrm << "mecount:" << std::hex << tid_stop_info.details.exception.data_count << ';';
for (int i = 0; i < tid_stop_info.details.exception.data_count; ++i)
- ostrm << "medata:" << std::hex << tid_stop_info.details.exception.data[i] << ";";
+ ostrm << "medata:" << std::hex << tid_stop_info.details.exception.data[i] << ';';
}
+
+ // Add expedited stack memory so stack backtracing doesn't need to read anything from the
+ // frame pointer chain.
+ StackMemoryMap stack_mmap;
+ ReadStackMemory (pid, tid, stack_mmap);
+ if (!stack_mmap.empty())
+ {
+ for (const auto &stack_memory : stack_mmap)
+ {
+ ostrm << "memory:" << HEXBASE << stack_memory.first << '=';
+ append_hex_value (ostrm, stack_memory.second.bytes, stack_memory.second.length, false);
+ ostrm << ';';
+ }
+ }
+
return SendPacket (ostrm.str ());
}
return SendPacket("E51");
@@ -4898,11 +4961,136 @@ get_integer_value_for_key_name_from_json (const char *key, const char *json_stri
}
rnb_err_t
+RNBRemote::HandlePacket_jThreadsInfo (const char *p)
+{
+ JSONGenerator::Array threads_array;
+
+ std::ostringstream json;
+ std::ostringstream reply_strm;
+ // If we haven't run the process yet, return an error.
+ if (m_ctx.HasValidProcessID())
+ {
+ nub_process_t pid = m_ctx.ProcessID();
+
+ nub_size_t numthreads = DNBProcessGetNumThreads (pid);
+ for (nub_size_t i = 0; i < numthreads; ++i)
+ {
+ nub_thread_t tid = DNBProcessGetThreadAtIndex (pid, i);
+
+ struct DNBThreadStopInfo tid_stop_info;
+
+ JSONGenerator::DictionarySP thread_dict_sp(new JSONGenerator::Dictionary());
+
+ thread_dict_sp->AddIntegerItem("tid", tid);
+
+ std::string reason_value("none");
+ if (DNBThreadGetStopReason (pid, tid, &tid_stop_info))
+ {
+ switch (tid_stop_info.reason)
+ {
+ case eStopTypeInvalid:
+ break;
+ case eStopTypeSignal:
+ if (tid_stop_info.details.signal.signo != 0)
+ reason_value = "signal";
+ break;
+ case eStopTypeException:
+ if (tid_stop_info.details.exception.type != 0)
+ reason_value = "exception";
+ break;
+ case eStopTypeExec:
+ reason_value = "exec";
+ break;
+ }
+ if (tid_stop_info.reason == eStopTypeSignal)
+ {
+ thread_dict_sp->AddIntegerItem("signal", tid_stop_info.details.signal.signo);
+ }
+ else if (tid_stop_info.reason == eStopTypeException && tid_stop_info.details.exception.type != 0)
+ {
+ thread_dict_sp->AddIntegerItem("metype", tid_stop_info.details.exception.type);
+ JSONGenerator::ArraySP medata_array_sp(new JSONGenerator::Array());
+ for (nub_size_t i=0; i<tid_stop_info.details.exception.data_count; ++i)
+ {
+ medata_array_sp->AddItem(JSONGenerator::IntegerSP(new JSONGenerator::Integer(tid_stop_info.details.exception.data[i])));
+ }
+ thread_dict_sp->AddItem("medata", medata_array_sp);
+ }
+ }
+
+ thread_dict_sp->AddStringItem("reason", reason_value);
+
+ const char *thread_name = DNBThreadGetName (pid, tid);
+ if (thread_name && thread_name[0])
+ thread_dict_sp->AddStringItem("name", thread_name);
+
+
+ thread_identifier_info_data_t thread_ident_info;
+ if (DNBThreadGetIdentifierInfo (pid, tid, &thread_ident_info))
+ {
+ if (thread_ident_info.dispatch_qaddr != 0)
+ thread_dict_sp->AddIntegerItem("qaddr", thread_ident_info.dispatch_qaddr);
+ }
+ DNBRegisterValue reg_value;
+
+ if (g_reg_entries != NULL)
+ {
+ JSONGenerator::DictionarySP registers_dict_sp(new JSONGenerator::Dictionary());
+
+ for (uint32_t reg = 0; reg < g_num_reg_entries; reg++)
+ {
+ // Expedite all registers in the first register set that aren't
+ // contained in other registers
+ if (g_reg_entries[reg].nub_info.set == 1 &&
+ g_reg_entries[reg].nub_info.value_regs == NULL)
+ {
+ if (!DNBThreadGetRegisterValueByID (pid, tid, g_reg_entries[reg].nub_info.set, g_reg_entries[reg].nub_info.reg, &reg_value))
+ continue;
+
+ std::ostringstream reg_num;
+ reg_num << std::dec << g_reg_entries[reg].gdb_regnum;
+ // Encode native byte ordered bytes as hex ascii
+ registers_dict_sp->AddBytesAsHexASCIIString(reg_num.str(), reg_value.value.v_uint8, g_reg_entries[reg].nub_info.size);
+ }
+ }
+ thread_dict_sp->AddItem("registers", registers_dict_sp);
+ }
+
+ // Add expedited stack memory so stack backtracing doesn't need to read anything from the
+ // frame pointer chain.
+ StackMemoryMap stack_mmap;
+ ReadStackMemory (pid, tid, stack_mmap);
+ if (!stack_mmap.empty())
+ {
+ JSONGenerator::ArraySP memory_array_sp(new JSONGenerator::Array());
+
+ for (const auto &stack_memory : stack_mmap)
+ {
+ JSONGenerator::DictionarySP stack_memory_sp(new JSONGenerator::Dictionary());
+ stack_memory_sp->AddIntegerItem("address", stack_memory.first);
+ stack_memory_sp->AddBytesAsHexASCIIString("bytes", stack_memory.second.bytes, stack_memory.second.length);
+ memory_array_sp->AddItem(stack_memory_sp);
+ }
+ thread_dict_sp->AddItem("memory", memory_array_sp);
+ }
+ threads_array.AddItem(thread_dict_sp);
+ }
+
+ std::ostringstream strm;
+ threads_array.Dump (strm);
+ std::string binary_packet = binary_encode_string (strm.str());
+ if (!binary_packet.empty())
+ return SendPacket (binary_packet.c_str());
+ }
+ return SendPacket ("E85");
+
+}
+
+rnb_err_t
RNBRemote::HandlePacket_jThreadExtendedInfo (const char *p)
{
nub_process_t pid;
std::ostringstream json;
- std::ostringstream reply_strm;
// If we haven't run the process yet, return an error.
if (!m_ctx.HasValidProcessID())
{
@@ -5132,8 +5320,7 @@ RNBRemote::HandlePacket_jThreadExtendedInfo (const char *p)
json << "}";
std::string json_quoted = binary_encode_string (json.str());
- reply_strm << json_quoted;
- return SendPacket (reply_strm.str());
+ return SendPacket (json_quoted);
}
}
return SendPacket ("OK");
diff --git a/lldb/tools/debugserver/source/RNBRemote.h b/lldb/tools/debugserver/source/RNBRemote.h
index 3fcccc2e8f3..00cfe7991f9 100644
--- a/lldb/tools/debugserver/source/RNBRemote.h
+++ b/lldb/tools/debugserver/source/RNBRemote.h
@@ -103,6 +103,7 @@ public:
query_gdb_server_version, // 'qGDBServerVersion'
query_process_info, // 'qProcessInfo'
json_query_thread_extended_info,// 'jThreadExtendedInfo'
+ json_query_threads_info, // 'jThreadsInfo'
pass_signals_to_inferior, // 'QPassSignals'
start_noack_mode, // 'QStartNoAckMode'
prefix_reg_packets_with_tid, // 'QPrefixRegisterPacketsWithThreadID
@@ -190,6 +191,7 @@ public:
rnb_err_t HandlePacket_qSyncThreadStateSupported (const char *p);
rnb_err_t HandlePacket_qThreadInfo (const char *p);
rnb_err_t HandlePacket_jThreadExtendedInfo (const char *p);
+ rnb_err_t HandlePacket_jThreadsInfo (const char *p);
rnb_err_t HandlePacket_qThreadExtraInfo (const char *p);
rnb_err_t HandlePacket_qThreadStopInfo (const char *p);
rnb_err_t HandlePacket_qHostInfo (const char *p);