summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJason Molenda <jmolenda@apple.com>2012-11-16 01:03:31 +0000
committerJason Molenda <jmolenda@apple.com>2012-11-16 01:03:31 +0000
commitaff2a269e315c66c4bf69c4e18114a801b3cfc43 (patch)
tree1f01bc6218a0c683e219d39384049549078647d0
parent234ba6f2cd3301794b834e530b6dcc4fe58872d0 (diff)
downloadbcm5719-llvm-aff2a269e315c66c4bf69c4e18114a801b3cfc43.tar.gz
bcm5719-llvm-aff2a269e315c66c4bf69c4e18114a801b3cfc43.zip
A change in how we search for saved register values unintentionally
allowed volatile registers to be returned up the stack. That leads to unexpected/incorrect values provided to the user and we need to avoid that. <rdar://problem/12714247> llvm-svn: 168123
-rw-r--r--lldb/source/Plugins/Process/Utility/RegisterContextLLDB.cpp38
-rw-r--r--lldb/source/Plugins/Process/Utility/RegisterContextLLDB.h2
-rw-r--r--lldb/source/Plugins/Process/Utility/UnwindLLDB.cpp10
-rw-r--r--lldb/source/Plugins/Process/Utility/UnwindLLDB.h7
4 files changed, 35 insertions, 22 deletions
diff --git a/lldb/source/Plugins/Process/Utility/RegisterContextLLDB.cpp b/lldb/source/Plugins/Process/Utility/RegisterContextLLDB.cpp
index d0d19283078..b8561dce047 100644
--- a/lldb/source/Plugins/Process/Utility/RegisterContextLLDB.cpp
+++ b/lldb/source/Plugins/Process/Utility/RegisterContextLLDB.cpp
@@ -903,7 +903,7 @@ RegisterContextLLDB::IsSkipFrame () const
// Answer the question: Where did THIS frame save the CALLER frame ("previous" frame)'s register value?
-bool
+enum UnwindLLDB::RegisterSearchResult
RegisterContextLLDB::SavedLocationForRegister (uint32_t lldb_regnum, lldb_private::UnwindLLDB::RegisterLocation &regloc)
{
// Have we already found this register location?
@@ -914,7 +914,7 @@ RegisterContextLLDB::SavedLocationForRegister (uint32_t lldb_regnum, lldb_privat
if (iterator != m_registers.end())
{
regloc = iterator->second;
- return true;
+ return UnwindLLDB::RegisterSearchResult::eRegisterFound;
}
}
@@ -937,7 +937,7 @@ RegisterContextLLDB::SavedLocationForRegister (uint32_t lldb_regnum, lldb_privat
regloc.type = UnwindLLDB::RegisterLocation::eRegisterValueInferred;
regloc.location.inferred_value = m_cfa;
m_registers[lldb_regnum] = regloc;
- return true;
+ return UnwindLLDB::RegisterSearchResult::eRegisterFound;
}
// Look through the available UnwindPlans for the register location.
@@ -955,7 +955,7 @@ RegisterContextLLDB::SavedLocationForRegister (uint32_t lldb_regnum, lldb_privat
{
UnwindLogMsg ("could not convert lldb regnum %d into %d RegisterKind reg numbering scheme",
lldb_regnum, (int) unwindplan_registerkind);
- return false;
+ return UnwindLLDB::RegisterSearchResult::eRegisterNotFound;
}
if (active_row->GetRegisterInfo (row_regnum, unwindplan_regloc))
{
@@ -993,7 +993,7 @@ RegisterContextLLDB::SavedLocationForRegister (uint32_t lldb_regnum, lldb_privat
else
UnwindLogMsg ("could not convert lldb regnum %d into %d RegisterKind reg numbering scheme",
lldb_regnum, (int) unwindplan_registerkind);
- return false;
+ return UnwindLLDB::RegisterSearchResult::eRegisterNotFound;
}
}
@@ -1064,7 +1064,7 @@ RegisterContextLLDB::SavedLocationForRegister (uint32_t lldb_regnum, lldb_privat
if (reg_info && abi->RegisterIsVolatile (reg_info))
{
UnwindLogMsg ("did not supply reg location for %d because it is volatile", lldb_regnum);
- return false;
+ return UnwindLLDB::RegisterSearchResult::eRegisterIsVolatile;
}
}
@@ -1076,11 +1076,11 @@ RegisterContextLLDB::SavedLocationForRegister (uint32_t lldb_regnum, lldb_privat
new_regloc.location.register_number = lldb_regnum;
m_registers[lldb_regnum] = new_regloc;
regloc = new_regloc;
- return true;
+ return UnwindLLDB::RegisterSearchResult::eRegisterFound;
}
else
UnwindLogMsg ("could not supply caller's reg %d location", lldb_regnum);
- return false;
+ return UnwindLLDB::RegisterSearchResult::eRegisterNotFound;
}
// unwindplan_regloc has valid contents about where to retrieve the register
@@ -1090,7 +1090,7 @@ RegisterContextLLDB::SavedLocationForRegister (uint32_t lldb_regnum, lldb_privat
new_regloc.type = UnwindLLDB::RegisterLocation::eRegisterNotSaved;
m_registers[lldb_regnum] = new_regloc;
UnwindLogMsg ("could not supply caller's reg %d location", lldb_regnum);
- return false;
+ return UnwindLLDB::RegisterSearchResult::eRegisterNotFound;
}
if (unwindplan_regloc.IsSame())
@@ -1098,11 +1098,11 @@ RegisterContextLLDB::SavedLocationForRegister (uint32_t lldb_regnum, lldb_privat
if (IsFrameZero ())
{
UnwindLogMsg ("could not supply caller's reg %d location", lldb_regnum);
- return false;
+ return UnwindLLDB::RegisterSearchResult::eRegisterNotFound;
}
else
{
- return false;
+ return UnwindLLDB::RegisterSearchResult::eRegisterNotFound;
}
}
@@ -1112,7 +1112,7 @@ RegisterContextLLDB::SavedLocationForRegister (uint32_t lldb_regnum, lldb_privat
regloc.type = UnwindLLDB::RegisterLocation::eRegisterValueInferred;
regloc.location.inferred_value = m_cfa + offset;
m_registers[lldb_regnum] = regloc;
- return true;
+ return UnwindLLDB::RegisterSearchResult::eRegisterFound;
}
if (unwindplan_regloc.IsAtCFAPlusOffset())
@@ -1121,7 +1121,7 @@ RegisterContextLLDB::SavedLocationForRegister (uint32_t lldb_regnum, lldb_privat
regloc.type = UnwindLLDB::RegisterLocation::eRegisterSavedAtMemoryLocation;
regloc.location.target_memory_location = m_cfa + offset;
m_registers[lldb_regnum] = regloc;
- return true;
+ return UnwindLLDB::RegisterSearchResult::eRegisterFound;
}
if (unwindplan_regloc.IsInOtherRegister())
@@ -1131,12 +1131,12 @@ RegisterContextLLDB::SavedLocationForRegister (uint32_t lldb_regnum, lldb_privat
if (!m_thread.GetRegisterContext()->ConvertBetweenRegisterKinds (unwindplan_registerkind, unwindplan_regnum, eRegisterKindLLDB, row_regnum_in_lldb))
{
UnwindLogMsg ("could not supply caller's reg %d location", lldb_regnum);
- return false;
+ return UnwindLLDB::RegisterSearchResult::eRegisterNotFound;
}
regloc.type = UnwindLLDB::RegisterLocation::eRegisterInRegister;
regloc.location.register_number = row_regnum_in_lldb;
m_registers[lldb_regnum] = regloc;
- return true;
+ return UnwindLLDB::RegisterSearchResult::eRegisterFound;
}
if (unwindplan_regloc.IsDWARFExpression() || unwindplan_regloc.IsAtDWARFExpression())
@@ -1157,25 +1157,25 @@ RegisterContextLLDB::SavedLocationForRegister (uint32_t lldb_regnum, lldb_privat
regloc.type = UnwindLLDB::RegisterLocation::eRegisterValueInferred;
regloc.location.inferred_value = val;
m_registers[lldb_regnum] = regloc;
- return true;
+ return UnwindLLDB::RegisterSearchResult::eRegisterFound;
}
else
{
regloc.type = UnwindLLDB::RegisterLocation::eRegisterSavedAtMemoryLocation;
regloc.location.target_memory_location = val;
m_registers[lldb_regnum] = regloc;
- return true;
+ return UnwindLLDB::RegisterSearchResult::eRegisterFound;
}
}
UnwindLogMsg ("tried to use IsDWARFExpression or IsAtDWARFExpression for reg %d but failed", lldb_regnum);
- return false;
+ return UnwindLLDB::RegisterSearchResult::eRegisterNotFound;
}
UnwindLogMsg ("could not supply caller's reg %d location", lldb_regnum);
// FIXME UnwindPlan::Row types atDWARFExpression and isDWARFExpression are unsupported.
- return false;
+ return UnwindLLDB::RegisterSearchResult::eRegisterNotFound;
}
// If the Full unwindplan has been determined to be incorrect, this method will
diff --git a/lldb/source/Plugins/Process/Utility/RegisterContextLLDB.h b/lldb/source/Plugins/Process/Utility/RegisterContextLLDB.h
index d659846f8a6..1b60996dfb5 100644
--- a/lldb/source/Plugins/Process/Utility/RegisterContextLLDB.h
+++ b/lldb/source/Plugins/Process/Utility/RegisterContextLLDB.h
@@ -131,7 +131,7 @@ private:
// If a non-volatile register (a "preserved" register) is requested mid-stack and no frames "below" the requested
// stack have saved the register anywhere, it is safe to assume that frame 0's register values are still the same
// as the requesting frame's.
- bool
+ lldb_private::UnwindLLDB::RegisterSearchResult
SavedLocationForRegister (uint32_t lldb_regnum, lldb_private::UnwindLLDB::RegisterLocation &regloc);
bool
diff --git a/lldb/source/Plugins/Process/Utility/UnwindLLDB.cpp b/lldb/source/Plugins/Process/Utility/UnwindLLDB.cpp
index 587ec88a73d..459a729b8c9 100644
--- a/lldb/source/Plugins/Process/Utility/UnwindLLDB.cpp
+++ b/lldb/source/Plugins/Process/Utility/UnwindLLDB.cpp
@@ -272,15 +272,21 @@ UnwindLLDB::SearchForSavedLocationForRegister (uint32_t lldb_regnum, lldb_privat
// isn't saved by frame_num, none of the frames lower on the stack will have a useful value.
if (pc_or_return_address_reg)
{
- if (m_frames[frame_num]->reg_ctx_lldb_sp->SavedLocationForRegister (lldb_regnum, regloc))
+ UnwindLLDB::RegisterSearchResult result;
+ result = m_frames[frame_num]->reg_ctx_lldb_sp->SavedLocationForRegister (lldb_regnum, regloc);
+ if (result == UnwindLLDB::RegisterSearchResult::eRegisterFound)
return true;
else
return false;
}
while (frame_num >= 0)
{
- if (m_frames[frame_num]->reg_ctx_lldb_sp->SavedLocationForRegister (lldb_regnum, regloc))
+ UnwindLLDB::RegisterSearchResult result;
+ result = m_frames[frame_num]->reg_ctx_lldb_sp->SavedLocationForRegister (lldb_regnum, regloc);
+ if (result == UnwindLLDB::RegisterSearchResult::eRegisterFound)
return true;
+ if (result == UnwindLLDB::RegisterSearchResult::eRegisterIsVolatile)
+ return false;
frame_num--;
}
return false;
diff --git a/lldb/source/Plugins/Process/Utility/UnwindLLDB.h b/lldb/source/Plugins/Process/Utility/UnwindLLDB.h
index 26dc968beeb..ed3be5bf5d5 100644
--- a/lldb/source/Plugins/Process/Utility/UnwindLLDB.h
+++ b/lldb/source/Plugins/Process/Utility/UnwindLLDB.h
@@ -30,6 +30,13 @@ public:
virtual
~UnwindLLDB() { }
+ enum RegisterSearchResult
+ {
+ eRegisterFound = 0,
+ eRegisterNotFound,
+ eRegisterIsVolatile
+ };
+
protected:
friend class lldb_private::RegisterContextLLDB;
OpenPOWER on IntegriCloud