summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--lldb/include/lldb/Core/ValueObject.h14
-rw-r--r--lldb/include/lldb/Core/ValueObjectConstResult.h18
-rw-r--r--lldb/include/lldb/Core/ValueObjectConstResultImpl.h9
-rw-r--r--lldb/source/Core/ValueObjectConstResult.cpp7
-rw-r--r--lldb/source/Core/ValueObjectConstResultImpl.cpp23
-rw-r--r--lldb/source/Expression/ClangExpressionDeclMap.cpp14
-rw-r--r--lldb/test/expression_command/issue_11588/Makefile5
-rw-r--r--lldb/test/expression_command/issue_11588/Test11588.py54
-rw-r--r--lldb/test/expression_command/issue_11588/main.cpp54
-rw-r--r--lldb/test/expression_command/issue_11588/s11588.py26
10 files changed, 219 insertions, 5 deletions
diff --git a/lldb/include/lldb/Core/ValueObject.h b/lldb/include/lldb/Core/ValueObject.h
index 9f4eaa546dd..1472ca3b435 100644
--- a/lldb/include/lldb/Core/ValueObject.h
+++ b/lldb/include/lldb/Core/ValueObject.h
@@ -696,7 +696,7 @@ public:
void
SetName (const ConstString &name);
- lldb::addr_t
+ virtual lldb::addr_t
GetAddressOf (bool scalar_is_load_address = true,
AddressType *address_type = NULL);
@@ -747,6 +747,18 @@ public:
virtual lldb::ValueObjectSP
AddressOf (Error &error);
+
+ virtual lldb::addr_t
+ GetLiveAddress()
+ {
+ return LLDB_INVALID_ADDRESS;
+ }
+
+ virtual void
+ SetLiveAddress(lldb::addr_t addr = LLDB_INVALID_ADDRESS,
+ AddressType address_type = eAddressTypeLoad)
+ {
+ }
virtual lldb::ValueObjectSP
CastPointerType (const char *name,
diff --git a/lldb/include/lldb/Core/ValueObjectConstResult.h b/lldb/include/lldb/Core/ValueObjectConstResult.h
index d82390ee291..ebba0619e4f 100644
--- a/lldb/include/lldb/Core/ValueObjectConstResult.h
+++ b/lldb/include/lldb/Core/ValueObjectConstResult.h
@@ -109,11 +109,29 @@ public:
virtual lldb::ValueObjectSP
AddressOf (Error &error);
+ virtual lldb::addr_t
+ GetAddressOf (bool scalar_is_load_address = true,
+ AddressType *address_type = NULL);
+
virtual size_t
GetPointeeData (DataExtractor& data,
uint32_t item_idx = 0,
uint32_t item_count = 1);
+ virtual lldb::addr_t
+ GetLiveAddress()
+ {
+ return m_impl.GetLiveAddress();
+ }
+
+ virtual void
+ SetLiveAddress(lldb::addr_t addr = LLDB_INVALID_ADDRESS,
+ AddressType address_type = eAddressTypeLoad)
+ {
+ m_impl.SetLiveAddress(addr,
+ address_type);
+ }
+
protected:
virtual bool
UpdateValue ();
diff --git a/lldb/include/lldb/Core/ValueObjectConstResultImpl.h b/lldb/include/lldb/Core/ValueObjectConstResultImpl.h
index 1b9c63fa4fa..b8c846fa1f5 100644
--- a/lldb/include/lldb/Core/ValueObjectConstResultImpl.h
+++ b/lldb/include/lldb/Core/ValueObjectConstResultImpl.h
@@ -61,14 +61,20 @@ public:
}
void
- SetLiveAddress(lldb::addr_t addr = LLDB_INVALID_ADDRESS)
+ SetLiveAddress(lldb::addr_t addr = LLDB_INVALID_ADDRESS,
+ AddressType address_type = eAddressTypeLoad)
{
m_live_address = addr;
+ m_live_address_type = address_type;
}
lldb::ValueObjectSP
DerefOnTarget();
+ virtual lldb::addr_t
+ GetAddressOf (bool scalar_is_load_address = true,
+ AddressType *address_type = NULL);
+
virtual size_t
GetPointeeData (DataExtractor& data,
uint32_t item_idx = 0,
@@ -78,6 +84,7 @@ private:
ValueObject *m_impl_backend;
lldb::addr_t m_live_address;
+ AddressType m_live_address_type;
lldb::ValueObjectSP m_load_addr_backend;
lldb::ValueObjectSP m_address_of_backend;
diff --git a/lldb/source/Core/ValueObjectConstResult.cpp b/lldb/source/Core/ValueObjectConstResult.cpp
index 9a23ca82a1b..fa1503f3217 100644
--- a/lldb/source/Core/ValueObjectConstResult.cpp
+++ b/lldb/source/Core/ValueObjectConstResult.cpp
@@ -324,6 +324,13 @@ ValueObjectConstResult::AddressOf (Error &error)
return m_impl.AddressOf(error);
}
+lldb::addr_t
+ValueObjectConstResult::GetAddressOf (bool scalar_is_load_address,
+ AddressType *address_type)
+{
+ return m_impl.GetAddressOf(scalar_is_load_address, address_type);
+}
+
ValueObject *
ValueObjectConstResult::CreateChildAtIndex (uint32_t idx, bool synthetic_array_member, int32_t synthetic_index)
{
diff --git a/lldb/source/Core/ValueObjectConstResultImpl.cpp b/lldb/source/Core/ValueObjectConstResultImpl.cpp
index 119ba015590..afe050291b0 100644
--- a/lldb/source/Core/ValueObjectConstResultImpl.cpp
+++ b/lldb/source/Core/ValueObjectConstResultImpl.cpp
@@ -40,7 +40,8 @@ using namespace lldb_private;
ValueObjectConstResultImpl::ValueObjectConstResultImpl (ValueObject* valobj,
lldb::addr_t live_address) :
m_impl_backend(valobj),
- m_live_address(live_address),
+ m_live_address(live_address),
+ m_live_address_type(eAddressTypeLoad),
m_load_addr_backend(),
m_address_of_backend()
{
@@ -201,6 +202,26 @@ ValueObjectConstResultImpl::AddressOf (Error &error)
return lldb::ValueObjectSP();
}
+lldb::addr_t
+ValueObjectConstResultImpl::GetAddressOf (bool scalar_is_load_address,
+ AddressType *address_type)
+{
+
+ if (m_impl_backend == NULL)
+ return 0;
+
+ if (m_live_address == LLDB_INVALID_ADDRESS)
+ {
+ return m_impl_backend->ValueObject::GetAddressOf (scalar_is_load_address,
+ address_type);
+ }
+
+ if (address_type)
+ *address_type = m_live_address_type;
+
+ return m_live_address;
+}
+
size_t
ValueObjectConstResultImpl::GetPointeeData (DataExtractor& data,
uint32_t item_idx,
diff --git a/lldb/source/Expression/ClangExpressionDeclMap.cpp b/lldb/source/Expression/ClangExpressionDeclMap.cpp
index e019334a5f7..e115054549a 100644
--- a/lldb/source/Expression/ClangExpressionDeclMap.cpp
+++ b/lldb/source/Expression/ClangExpressionDeclMap.cpp
@@ -396,13 +396,23 @@ ClangExpressionDeclMap::CompleteResultVariable (lldb::ClangExpressionVariableSP
{
// The reference comes from the program. We need to set up a live SP for it.
+ unsigned long long address = value.GetScalar().ULongLong();
+ AddressType address_type = value.GetValueAddressType();
+
pvar_sp->m_live_sp = ValueObjectConstResult::Create(m_parser_vars->m_exe_ctx->GetBestExecutionContextScope(),
pvar_sp->GetTypeFromUser().GetASTContext(),
pvar_sp->GetTypeFromUser().GetOpaqueQualType(),
pvar_sp->GetName(),
- value.GetScalar().ULongLong(),
- value.GetValueAddressType(),
+ address,
+ address_type,
pvar_sp->GetByteSize());
+
+ // if the frozen object does not yet have a valid live address we replicate the live_sp address
+ // to it. this solves the issue where synthetic children providers are unable to access
+ // the address-of result for objects obtained by casting the result of pointer arithmetic
+ // performed by the expression parser, as in: print *((ClassType*)(value-1))
+ if (pvar_sp->m_frozen_sp->GetLiveAddress() == LLDB_INVALID_ADDRESS)
+ pvar_sp->m_frozen_sp->SetLiveAddress(address);
}
if (pvar_sp->m_flags & ClangExpressionVariable::EVNeedsFreezeDry)
diff --git a/lldb/test/expression_command/issue_11588/Makefile b/lldb/test/expression_command/issue_11588/Makefile
new file mode 100644
index 00000000000..8a7102e347a
--- /dev/null
+++ b/lldb/test/expression_command/issue_11588/Makefile
@@ -0,0 +1,5 @@
+LEVEL = ../../make
+
+CXX_SOURCES := main.cpp
+
+include $(LEVEL)/Makefile.rules
diff --git a/lldb/test/expression_command/issue_11588/Test11588.py b/lldb/test/expression_command/issue_11588/Test11588.py
new file mode 100644
index 00000000000..ba0c1c622db
--- /dev/null
+++ b/lldb/test/expression_command/issue_11588/Test11588.py
@@ -0,0 +1,54 @@
+"""
+Test the solution to issue 11581.
+valobj.AddressOf() returns None when an address is
+expected in a SyntheticChildrenProvider
+"""
+
+import os, time
+import unittest2
+import lldb
+from lldbtest import *
+
+class Issue11581TestCase(TestBase):
+
+ mydir = os.path.join("expression_command", "issue_11588")
+
+ def test_11581_commands(self):
+ # This is the function to remove the custom commands in order to have a
+ # clean slate for the next test case.
+ def cleanup():
+ self.runCmd('type synthetic clear', check=False)
+
+ # Execute the cleanup function during test case tear down.
+ self.addTearDownHook(cleanup)
+
+ """valobj.AddressOf() should return correct values."""
+ self.buildDefault()
+
+ self.runCmd("file a.out", CURRENT_EXECUTABLE_SET)
+
+ self.runCmd("breakpoint set --name main")
+
+ self.runCmd("run", RUN_SUCCEEDED)
+
+ self.runCmd("next", RUN_SUCCEEDED)
+ self.runCmd("next", RUN_SUCCEEDED)
+ self.runCmd("next", RUN_SUCCEEDED)
+ self.runCmd("next", RUN_SUCCEEDED)
+ self.runCmd("next", RUN_SUCCEEDED)
+
+ self.runCmd("command script import s11588.py")
+ self.runCmd("type synthetic add --python-class s11588.Issue11581SyntheticProvider StgClosure")
+
+ self.expect("print *((StgClosure*)(r14-1))",
+ substrs = ["(StgClosure) $",
+ "(StgClosure *) &$0 = 0x",
+ "(long) addr = ",
+ "(long) load_address = "])
+
+
+if __name__ == '__main__':
+ import atexit
+ lldb.SBDebugger.Initialize()
+ atexit.register(lambda: lldb.SBDebugger.Terminate())
+ unittest2.main()
diff --git a/lldb/test/expression_command/issue_11588/main.cpp b/lldb/test/expression_command/issue_11588/main.cpp
new file mode 100644
index 00000000000..45067b7e702
--- /dev/null
+++ b/lldb/test/expression_command/issue_11588/main.cpp
@@ -0,0 +1,54 @@
+//
+// 11588.cpp
+//
+
+#include <iostream>
+
+class StgInfoTable {};
+
+class StgHeader
+{
+private:
+ StgInfoTable* info;
+public:
+ StgHeader()
+ {
+ info = new StgInfoTable();
+ }
+ ~StgHeader()
+ {
+ delete info;
+ }
+};
+
+class StgClosure
+{
+private:
+ StgHeader header;
+ StgClosure* payload[1];
+public:
+ StgClosure(bool make_payload = true)
+ {
+ if (make_payload)
+ payload[0] = new StgClosure(false);
+ else
+ payload[0] = NULL;
+ }
+ ~StgClosure()
+ {
+ if (payload[0])
+ delete payload[0];
+ }
+};
+
+typedef unsigned long long int ptr_type;
+
+int main()
+{
+ StgClosure* r14_ = new StgClosure();
+ r14_ = (StgClosure*)(((ptr_type)r14_ | 0x01)); // set the LSB to 1 for tagging
+ ptr_type r14 = (ptr_type)r14_;
+ int x = 0;
+ x = 3;
+ return (x-1);
+}
diff --git a/lldb/test/expression_command/issue_11588/s11588.py b/lldb/test/expression_command/issue_11588/s11588.py
new file mode 100644
index 00000000000..01bb09a1b0d
--- /dev/null
+++ b/lldb/test/expression_command/issue_11588/s11588.py
@@ -0,0 +1,26 @@
+class Issue11581SyntheticProvider(object):
+ def __init__(self, valobj, dict):
+ self.valobj = valobj
+ self.addrOf = valobj.AddressOf()
+ self.addr = valobj.GetAddress()
+ self.load_address = valobj.GetLoadAddress()
+
+ def num_children(self):
+ return 3;
+
+ def get_child_at_index(self, index):
+ if index == 0:
+ return self.addrOf
+ if index == 1:
+ return self.valobj.CreateValueFromExpression("addr", str(self.addr))
+ if index == 2:
+ return self.valobj.CreateValueFromExpression("load_address", str(self.load_address))
+
+ def get_child_index(self, name):
+ if name == "addrOf":
+ return 0
+ if name == "addr":
+ return 1
+ if name == "load_address":
+ return 2
+
OpenPOWER on IntegriCloud