summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGreg Clayton <gclayton@apple.com>2012-07-11 22:18:24 +0000
committerGreg Clayton <gclayton@apple.com>2012-07-11 22:18:24 +0000
commitc3a86bf9f0e774b68b41582937a076d6706f1d30 (patch)
treee509ab7f6dcd2305671a7af9efbe086167b1e745
parent570ae0b1f73f1c2d710648289b4b1088960cf010 (diff)
downloadbcm5719-llvm-c3a86bf9f0e774b68b41582937a076d6706f1d30.tar.gz
bcm5719-llvm-c3a86bf9f0e774b68b41582937a076d6706f1d30.zip
Modifying the "address" format, which prints a pointer and a description of what it points to, to detect when the deref of that pointer points to something valid. So if you have:
% cat sp.cpp #include <tr1/memory> class A { public: A (): m_i (12) {} virtual ~A() {} private: int m_i; }; int main (int argc, char const *argv[], char const *envp[]) { A *a_pointers[2] = { NULL, NULL }; A a1; A a2; a_pointers[0] = &a1; a_pointers[1] = &a2; return 0; } And you stop at the "return 0", you can now read memory using the "address" format and see: (lldb) memory read --format address `&a_pointers` 0x7fff5fbff870: 0x00007fff5fbff860 -> 0x00000001000010b0 vtable for A + 16 0x7fff5fbff878: 0x00007fff5fbff850 -> 0x00000001000010b0 vtable for A + 16 0x7fff5fbff880: 0x00007fff5fbff8d0 0x7fff5fbff888: 0x00007fff5fbff8c0 0x7fff5fbff890: 0x0000000000000001 0x7fff5fbff898: 0x36d54c275add2294 0x7fff5fbff8a0: 0x00007fff5fbff8b0 0x7fff5fbff8a8: 0x0000000100000bb4 a.out`start + 52 Note the extra dereference that was applied to 0x00007fff5fbff860 and 0x00007fff5fbff850 so we can see that these are "A" classes. llvm-svn: 160085
-rw-r--r--lldb/include/lldb/Core/Address.h4
-rw-r--r--lldb/source/Core/Address.cpp36
-rw-r--r--lldb/source/Core/DataExtractor.cpp21
3 files changed, 51 insertions, 10 deletions
diff --git a/lldb/include/lldb/Core/Address.h b/lldb/include/lldb/Core/Address.h
index 423bafa69c4..6a97e87b87c 100644
--- a/lldb/include/lldb/Core/Address.h
+++ b/lldb/include/lldb/Core/Address.h
@@ -86,8 +86,10 @@ public:
///< and file and line), to information about what the pointer points to
///< if the address is in a section (section of pointers, c strings, etc).
DumpStyleResolvedDescriptionNoModule,
- DumpStyleDetailedSymbolContext ///< Detailed symbol context information for an address for all symbol
+ DumpStyleDetailedSymbolContext, ///< Detailed symbol context information for an address for all symbol
///< context members.
+ DumpStyleResolvedPointerDescription ///< Dereference a pointer at the current address and then lookup the
+ ///< dereferenced address using DumpStyleResolvedDescription
} DumpStyle;
//------------------------------------------------------------------
diff --git a/lldb/source/Core/Address.cpp b/lldb/source/Core/Address.cpp
index e4dc06312f3..0308812bc56 100644
--- a/lldb/source/Core/Address.cpp
+++ b/lldb/source/Core/Address.cpp
@@ -354,9 +354,10 @@ Address::SetOpcodeLoadAddress (lldb::addr_t load_addr, Target *target)
bool
Address::Dump (Stream *s, ExecutionContextScope *exe_scope, DumpStyle style, DumpStyle fallback_style, uint32_t addr_size) const
{
- // If the section was NULL, only load address is going to work.
+ // If the section was NULL, only load address is going to work unless we are
+ // trying to deref a pointer
SectionSP section_sp (GetSection());
- if (!section_sp)
+ if (!section_sp && style != DumpStyleResolvedPointerDescription)
style = DumpStyleLoadAddress;
ExecutionContext exe_ctx (exe_scope);
@@ -728,6 +729,37 @@ Address::Dump (Stream *s, ExecutionContextScope *exe_scope, DumpStyle style, Dum
return false;
}
break;
+ case DumpStyleResolvedPointerDescription:
+ {
+ Process *process = exe_ctx.GetProcessPtr();
+ if (process)
+ {
+ addr_t load_addr = GetLoadAddress (target);
+ if (load_addr != LLDB_INVALID_ADDRESS)
+ {
+ Error memory_error;
+ addr_t dereferenced_load_addr = process->ReadPointerFromMemory(load_addr, memory_error);
+ if (dereferenced_load_addr != LLDB_INVALID_ADDRESS)
+ {
+ Address dereferenced_addr;
+ if (dereferenced_addr.SetLoadAddress(dereferenced_load_addr, target))
+ {
+ StreamString strm;
+ if (dereferenced_addr.Dump (&strm, exe_scope, DumpStyleResolvedDescription, DumpStyleInvalid, addr_size))
+ {
+ s->Address (dereferenced_load_addr, addr_size, " -> ", " ");
+ s->Write(strm.GetData(), strm.GetSize());
+ return true;
+ }
+ }
+ }
+ }
+ }
+ if (fallback_style != DumpStyleInvalid)
+ return Dump (s, exe_scope, fallback_style, DumpStyleInvalid, addr_size);
+ return false;
+ }
+ break;
}
return true;
diff --git a/lldb/source/Core/DataExtractor.cpp b/lldb/source/Core/DataExtractor.cpp
index da52be8d865..24d1dc12c27 100644
--- a/lldb/source/Core/DataExtractor.cpp
+++ b/lldb/source/Core/DataExtractor.cpp
@@ -1737,14 +1737,21 @@ DataExtractor::Dump (Stream *s,
{
TargetSP target_sp (exe_scope->CalculateTarget());
lldb_private::Address so_addr;
- if (target_sp && target_sp->GetSectionLoadList().ResolveLoadAddress(addr, so_addr))
+ if (target_sp)
{
- s->PutChar(' ');
- so_addr.Dump (s,
- exe_scope,
- Address::DumpStyleResolvedDescription,
- Address::DumpStyleModuleWithFileAddress);
- break;
+ if (target_sp->GetSectionLoadList().ResolveLoadAddress(addr, so_addr))
+ {
+ s->PutChar(' ');
+ so_addr.Dump (s,
+ exe_scope,
+ Address::DumpStyleResolvedDescription,
+ Address::DumpStyleModuleWithFileAddress);
+ }
+ else
+ {
+ so_addr.SetOffset(addr);
+ so_addr.Dump (s, exe_scope, Address::DumpStyleResolvedPointerDescription);
+ }
}
}
}
OpenPOWER on IntegriCloud