[llvm-branch-commits] [lldb] r179679 - Merge trunk rev 179594 back into the Windows branch.
Carlo Kok
ck at remobjects.com
Wed Apr 17 01:38:53 PDT 2013
Modified: lldb/branches/windows/source/Expression/ClangUserExpression.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/windows/source/Expression/ClangUserExpression.cpp?rev=179679&r1=179678&r2=179679&view=diff
==============================================================================
--- lldb/branches/windows/source/Expression/ClangUserExpression.cpp (original)
+++ lldb/branches/windows/source/Expression/ClangUserExpression.cpp Wed Apr 17 03:38:48 2013
@@ -29,6 +29,7 @@
#include "lldb/Expression/ClangFunction.h"
#include "lldb/Expression/ClangUserExpression.h"
#include "lldb/Expression/ExpressionSourceCode.h"
+#include "lldb/Expression/Materializer.h"
#include "lldb/Host/Host.h"
#include "lldb/Symbol/Block.h"
#include "lldb/Symbol/ClangASTContext.h"
@@ -106,7 +107,7 @@ ClangUserExpression::ASTTransformer (cla
void
ClangUserExpression::ScanContext(ExecutionContext &exe_ctx, Error &err)
{
- lldb::LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
+ Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
if (log)
log->Printf("ClangUserExpression::ScanContext()");
@@ -228,19 +229,100 @@ ClangUserExpression::ScanContext(Executi
// that this is a method of a class in whatever runtime the debug info says the object pointer
// belongs to. Do that here.
- ClangASTMetadata *metadata = ClangASTContext::GetMetadata (&decl_context->getParentASTContext(), (uintptr_t) function_decl);
+ ClangASTMetadata *metadata = ClangASTContext::GetMetadata (&decl_context->getParentASTContext(), function_decl);
if (metadata && metadata->HasObjectPtr())
{
lldb::LanguageType language = metadata->GetObjectPtrLanguage();
if (language == lldb::eLanguageTypeC_plus_plus)
{
+ if (m_enforce_valid_object)
+ {
+ lldb::VariableListSP variable_list_sp (function_block->GetBlockVariableList (true));
+
+ const char *thisErrorString = "Stopped in a context claiming to capture a C++ object pointer, but 'this' isn't available; pretending we are in a generic context";
+
+ if (!variable_list_sp)
+ {
+ err.SetErrorString(thisErrorString);
+ return;
+ }
+
+ lldb::VariableSP this_var_sp (variable_list_sp->FindVariable(ConstString("this")));
+
+ if (!this_var_sp ||
+ !this_var_sp->IsInScope(frame) ||
+ !this_var_sp->LocationIsValidForFrame (frame))
+ {
+ err.SetErrorString(thisErrorString);
+ return;
+ }
+ }
+
m_cplusplus = true;
m_needs_object_ptr = true;
}
else if (language == lldb::eLanguageTypeObjC)
{
- m_objectivec = true;
- m_needs_object_ptr = true;
+ if (m_enforce_valid_object)
+ {
+ lldb::VariableListSP variable_list_sp (function_block->GetBlockVariableList (true));
+
+ const char *selfErrorString = "Stopped in a context claiming to capture an Objective-C object pointer, but 'self' isn't available; pretending we are in a generic context";
+
+ if (!variable_list_sp)
+ {
+ err.SetErrorString(selfErrorString);
+ return;
+ }
+
+ lldb::VariableSP self_variable_sp = variable_list_sp->FindVariable(ConstString("self"));
+
+ if (!self_variable_sp ||
+ !self_variable_sp->IsInScope(frame) ||
+ !self_variable_sp->LocationIsValidForFrame (frame))
+ {
+ err.SetErrorString(selfErrorString);
+ return;
+ }
+
+ Type *self_type = self_variable_sp->GetType();
+
+ if (!self_type)
+ {
+ err.SetErrorString(selfErrorString);
+ return;
+ }
+
+ lldb::clang_type_t self_opaque_type = self_type->GetClangForwardType();
+
+ if (!self_opaque_type)
+ {
+ err.SetErrorString(selfErrorString);
+ return;
+ }
+
+ clang::QualType self_qual_type = clang::QualType::getFromOpaquePtr(self_opaque_type);
+
+ if (self_qual_type->isObjCClassType())
+ {
+ return;
+ }
+ else if (self_qual_type->isObjCObjectPointerType())
+ {
+ m_objectivec = true;
+ m_needs_object_ptr = true;
+ }
+ else
+ {
+ err.SetErrorString(selfErrorString);
+ return;
+ }
+ }
+ else
+ {
+ m_objectivec = true;
+ m_needs_object_ptr = true;
+ }
}
}
}
@@ -291,7 +373,7 @@ ClangUserExpression::Parse (Stream &erro
lldb_private::ExecutionPolicy execution_policy,
bool keep_result_in_memory)
{
- lldb::LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
+ Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
Error err;
@@ -349,9 +431,11 @@ ClangUserExpression::Parse (Stream &erro
// Parse the expression
//
+ m_materializer_ap.reset(new Materializer());
+
m_expr_decl_map.reset(new ClangExpressionDeclMap(keep_result_in_memory, exe_ctx));
- if (!m_expr_decl_map->WillParse(exe_ctx))
+ if (!m_expr_decl_map->WillParse(exe_ctx, m_materializer_ap.get()))
{
error_stream.PutCString ("error: current process state is unsuitable for expression parsing\n");
return false;
@@ -379,30 +463,18 @@ ClangUserExpression::Parse (Stream &erro
//////////////////////////////////////////////////////////////////////////////////////////
// Prepare the output of the parser for execution, evaluating it statically if possible
//
-
- if (execution_policy != eExecutionPolicyNever && process)
- m_data_allocator.reset(new ProcessDataAllocator(*process));
-
- Error jit_error = parser.PrepareForExecution (m_jit_alloc,
- m_jit_start_addr,
+
+ Error jit_error = parser.PrepareForExecution (m_jit_start_addr,
m_jit_end_addr,
+ m_execution_unit_ap,
exe_ctx,
- m_data_allocator.get(),
m_evaluated_statically,
m_const_result,
execution_policy);
-
- if (log && m_data_allocator.get())
- {
- StreamString dump_string;
- m_data_allocator->Dump(dump_string);
-
- log->Printf("Data buffer contents:\n%s", dump_string.GetString().c_str());
- }
if (jit_error.Success())
{
- if (process && m_jit_alloc != LLDB_INVALID_ADDRESS)
+ if (process && m_jit_start_addr != LLDB_INVALID_ADDRESS)
m_jit_process_wp = lldb::ProcessWP(process->shared_from_this());
return true;
}
@@ -424,7 +496,7 @@ ClangUserExpression::PrepareToExecuteJIT
lldb::addr_t &object_ptr,
lldb::addr_t &cmd_ptr)
{
- lldb::LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
+ Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
lldb::TargetSP target;
lldb::ProcessSP process;
@@ -537,12 +609,16 @@ ClangUserExpression::GetThreadPlanToExec
// ClangUserExpression resources before the thread plan finishes execution in the target. But because we are
// forcing unwind_on_error to be true here, in practical terms that can't happen.
+ const bool stop_others = true;
+ const bool unwind_on_error = true;
+ const bool ignore_breakpoints = false;
return ClangFunction::GetThreadPlanToCallFunction (exe_ctx,
m_jit_start_addr,
struct_address,
error_stream,
- true,
- true,
+ stop_others,
+ unwind_on_error,
+ ignore_breakpoints,
(m_needs_object_ptr ? &object_ptr : NULL),
(m_needs_object_ptr && m_objectivec) ? &cmd_ptr : NULL);
}
@@ -555,7 +631,7 @@ ClangUserExpression::FinalizeJITExecutio
{
Error expr_error;
- lldb::LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
+ Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
if (log)
{
@@ -593,7 +669,8 @@ ClangUserExpression::FinalizeJITExecutio
ExecutionResults
ClangUserExpression::Execute (Stream &error_stream,
ExecutionContext &exe_ctx,
- bool discard_on_error,
+ bool unwind_on_error,
+ bool ignore_breakpoints,
ClangUserExpression::ClangUserExpressionSP &shared_ptr_to_me,
lldb::ClangExpressionVariableSP &result,
bool run_others,
@@ -601,7 +678,7 @@ ClangUserExpression::Execute (Stream &er
{
// The expression log is quite verbose, and if you're just tracking the execution of the
// expression, it's quite convenient to have these logs come out with the STEP log as well.
- lldb::LogSP log(lldb_private::GetLogIfAnyCategoriesSet (LIBLLDB_LOG_EXPRESSIONS | LIBLLDB_LOG_STEP));
+ Log *log(lldb_private::GetLogIfAnyCategoriesSet (LIBLLDB_LOG_EXPRESSIONS | LIBLLDB_LOG_STEP));
if (m_jit_start_addr != LLDB_INVALID_ADDRESS)
{
@@ -617,19 +694,20 @@ ClangUserExpression::Execute (Stream &er
}
const bool stop_others = true;
- const bool try_all_threads = true;
+ const bool try_all_threads = run_others;
Address wrapper_address (m_jit_start_addr);
lldb::ThreadPlanSP call_plan_sp(new ThreadPlanCallUserExpression (exe_ctx.GetThreadRef(),
wrapper_address,
struct_address,
stop_others,
- discard_on_error,
+ unwind_on_error,
+ ignore_breakpoints,
(m_needs_object_ptr ? &object_ptr : NULL),
((m_needs_object_ptr && m_objectivec) ? &cmd_ptr : NULL),
shared_ptr_to_me));
- if (!call_plan_sp || !call_plan_sp->ValidatePlan (NULL))
+ if (!call_plan_sp || !call_plan_sp->ValidatePlan (&error_stream))
return eExecutionSetupError;
lldb::addr_t function_stack_pointer = static_cast<ThreadPlanCallFunction *>(call_plan_sp.get())->GetFunctionStackPointer();
@@ -644,7 +722,8 @@ ClangUserExpression::Execute (Stream &er
call_plan_sp,
stop_others,
try_all_threads,
- discard_on_error,
+ unwind_on_error,
+ ignore_breakpoints,
timeout_usec,
error_stream);
@@ -654,7 +733,7 @@ ClangUserExpression::Execute (Stream &er
if (log)
log->Printf("-- [ClangUserExpression::Execute] Execution of expression completed --");
- if (execution_result == eExecutionInterrupted)
+ if (execution_result == eExecutionInterrupted || execution_result == eExecutionHitBreakpoint)
{
const char *error_desc = NULL;
@@ -669,10 +748,11 @@ ClangUserExpression::Execute (Stream &er
else
error_stream.Printf ("Execution was interrupted.");
- if (discard_on_error)
- error_stream.Printf ("\nThe process has been returned to the state before execution.");
+ if ((execution_result == eExecutionInterrupted && unwind_on_error)
+ || (execution_result == eExecutionHitBreakpoint && ignore_breakpoints))
+ error_stream.Printf ("\nThe process has been returned to the state before expression evaluation.");
else
- error_stream.Printf ("\nThe process has been left at the point where it was interrupted.");
+ error_stream.Printf ("\nThe process has been left at the point where it was interrupted, use \"thread return -x\" to return to the state before expression evaluation.");
return execution_result;
}
@@ -702,7 +782,8 @@ ClangUserExpression::Evaluate (Execution
lldb_private::ExecutionPolicy execution_policy,
lldb::LanguageType language,
ResultType desired_type,
- bool discard_on_error,
+ bool unwind_on_error,
+ bool ignore_breakpoints,
const char *expr_cstr,
const char *expr_prefix,
lldb::ValueObjectSP &result_valobj_sp,
@@ -714,7 +795,8 @@ ClangUserExpression::Evaluate (Execution
execution_policy,
language,
desired_type,
- discard_on_error,
+ unwind_on_error,
+ ignore_breakpoints,
expr_cstr,
expr_prefix,
result_valobj_sp,
@@ -728,7 +810,8 @@ ClangUserExpression::EvaluateWithError (
lldb_private::ExecutionPolicy execution_policy,
lldb::LanguageType language,
ResultType desired_type,
- bool discard_on_error,
+ bool unwind_on_error,
+ bool ignore_breakpoints,
const char *expr_cstr,
const char *expr_prefix,
lldb::ValueObjectSP &result_valobj_sp,
@@ -736,7 +819,7 @@ ClangUserExpression::EvaluateWithError (
bool run_others,
uint32_t timeout_usec)
{
- lldb::LogSP log(lldb_private::GetLogIfAnyCategoriesSet (LIBLLDB_LOG_EXPRESSIONS | LIBLLDB_LOG_STEP));
+ Log *log(lldb_private::GetLogIfAnyCategoriesSet (LIBLLDB_LOG_EXPRESSIONS | LIBLLDB_LOG_STEP));
ExecutionResults execution_results = eExecutionSetupError;
@@ -807,7 +890,8 @@ ClangUserExpression::EvaluateWithError (
execution_results = user_expression_sp->Execute (error_stream,
exe_ctx,
- discard_on_error,
+ unwind_on_error,
+ ignore_breakpoints,
user_expression_sp,
expr_result,
run_others,
Modified: lldb/branches/windows/source/Expression/ClangUtilityFunction.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/windows/source/Expression/ClangUtilityFunction.cpp?rev=179679&r1=179678&r2=179679&view=diff
==============================================================================
--- lldb/branches/windows/source/Expression/ClangUtilityFunction.cpp (original)
+++ lldb/branches/windows/source/Expression/ClangUtilityFunction.cpp Wed Apr 17 03:38:48 2013
@@ -22,6 +22,7 @@
#include "lldb/Expression/ClangExpressionDeclMap.h"
#include "lldb/Expression/ClangExpressionParser.h"
#include "lldb/Expression/ClangUtilityFunction.h"
+#include "lldb/Expression/ExpressionSourceCode.h"
#include "lldb/Host/Host.h"
#include "lldb/Target/ExecutionContext.h"
#include "lldb/Target/Target.h"
@@ -40,9 +41,11 @@ using namespace lldb_private;
ClangUtilityFunction::ClangUtilityFunction (const char *text,
const char *name) :
ClangExpression (),
- m_function_text (text),
+ m_function_text (ExpressionSourceCode::g_expression_prefix),
m_function_name (name)
{
+ if (text && text[0])
+ m_function_text.append (text);
}
ClangUtilityFunction::~ClangUtilityFunction ()
@@ -65,8 +68,6 @@ bool
ClangUtilityFunction::Install (Stream &error_stream,
ExecutionContext &exe_ctx)
{
- lldb::LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
-
if (m_jit_start_addr != LLDB_INVALID_ADDRESS)
{
error_stream.PutCString("error: already installed\n");
@@ -101,9 +102,7 @@ ClangUtilityFunction::Install (Stream &e
m_expr_decl_map.reset(new ClangExpressionDeclMap(keep_result_in_memory, exe_ctx));
- m_data_allocator.reset(new ProcessDataAllocator(*process));
-
- if (!m_expr_decl_map->WillParse(exe_ctx))
+ if (!m_expr_decl_map->WillParse(exe_ctx, NULL))
{
error_stream.PutCString ("error: current process state is unsuitable for expression parsing\n");
return false;
@@ -130,23 +129,14 @@ ClangUtilityFunction::Install (Stream &e
bool evaluated_statically = false; // should stay that way
- Error jit_error = parser.PrepareForExecution (m_jit_alloc,
- m_jit_start_addr,
- m_jit_end_addr,
+ Error jit_error = parser.PrepareForExecution (m_jit_start_addr,
+ m_jit_end_addr,
+ m_execution_unit_ap,
exe_ctx,
- m_data_allocator.get(),
evaluated_statically,
const_result,
eExecutionPolicyAlways);
- if (log)
- {
- StreamString dump_string;
- m_data_allocator->Dump(dump_string);
-
- log->Printf("Data buffer contents:\n%s", dump_string.GetString().c_str());
- }
-
if (m_jit_start_addr != LLDB_INVALID_ADDRESS)
m_jit_process_wp = lldb::ProcessWP(process->shared_from_this());
Modified: lldb/branches/windows/source/Expression/DWARFExpression.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/windows/source/Expression/DWARFExpression.cpp?rev=179679&r1=179678&r2=179679&view=diff
==============================================================================
--- lldb/branches/windows/source/Expression/DWARFExpression.cpp (original)
+++ lldb/branches/windows/source/Expression/DWARFExpression.cpp Wed Apr 17 03:38:48 2013
@@ -233,7 +233,7 @@ DWARFExpression::DWARFExpression(const D
}
-DWARFExpression::DWARFExpression(const DataExtractor& data, uint32_t data_offset, uint32_t data_length) :
+DWARFExpression::DWARFExpression(const DataExtractor& data, lldb::offset_t data_offset, lldb::offset_t data_length) :
m_data(data, data_offset, data_length),
m_reg_kind (eRegisterKindDWARF),
m_loclist_slide(LLDB_INVALID_ADDRESS)
@@ -261,7 +261,7 @@ DWARFExpression::SetOpcodeData (const Da
}
void
-DWARFExpression::CopyOpcodeData (const DataExtractor& data, uint32_t data_offset, uint32_t data_length)
+DWARFExpression::CopyOpcodeData (const DataExtractor& data, lldb::offset_t data_offset, lldb::offset_t data_length)
{
const uint8_t *bytes = data.PeekData(data_offset, data_length);
if (bytes)
@@ -273,21 +273,21 @@ DWARFExpression::CopyOpcodeData (const D
}
void
-DWARFExpression::SetOpcodeData (const DataExtractor& data, uint32_t data_offset, uint32_t data_length)
+DWARFExpression::SetOpcodeData (const DataExtractor& data, lldb::offset_t data_offset, lldb::offset_t data_length)
{
m_data.SetData(data, data_offset, data_length);
}
void
-DWARFExpression::DumpLocation (Stream *s, uint32_t offset, uint32_t length, lldb::DescriptionLevel level, ABI *abi) const
+DWARFExpression::DumpLocation (Stream *s, lldb::offset_t offset, lldb::offset_t length, lldb::DescriptionLevel level, ABI *abi) const
{
if (!m_data.ValidOffsetForDataOfSize(offset, length))
return;
- const uint32_t start_offset = offset;
- const uint32_t end_offset = offset + length;
+ const lldb::offset_t start_offset = offset;
+ const lldb::offset_t end_offset = offset + length;
while (m_data.ValidOffset(offset) && offset < end_offset)
{
- const uint32_t op_offset = offset;
+ const lldb::offset_t op_offset = offset;
const uint8_t op = m_data.GetU8(&offset);
switch (level)
@@ -308,7 +308,7 @@ DWARFExpression::DumpLocation (Stream *s
if (level == lldb::eDescriptionLevelFull)
break;
// Fall through for verbose and print offset and DW_OP prefix..
- s->Printf("0x%8.8x: %s", op_offset, op >= DW_OP_APPLE_uninit ? "DW_OP_APPLE_" : "DW_OP_");
+ s->Printf("0x%8.8" PRIx64 ": %s", op_offset, op >= DW_OP_APPLE_uninit ? "DW_OP_APPLE_" : "DW_OP_");
break;
}
@@ -506,7 +506,7 @@ DWARFExpression::DumpLocation (Stream *s
case DW_OP_regx: // 0x90 1 ULEB128 register
{
- uint64_t reg_num = m_data.GetULEB128(&offset);
+ uint32_t reg_num = m_data.GetULEB128(&offset);
if (abi)
{
RegisterInfo reg_info;
@@ -524,7 +524,7 @@ DWARFExpression::DumpLocation (Stream *s
}
}
}
- s->Printf("DW_OP_regx(%" PRIu64 ")", reg_num); break;
+ s->Printf("DW_OP_regx(%" PRIu32 ")", reg_num); break;
}
break;
case DW_OP_fbreg: // 0x91 1 SLEB128 offset
@@ -551,7 +551,7 @@ DWARFExpression::DumpLocation (Stream *s
}
}
}
- s->Printf("DW_OP_bregx(reg=%u,offset=%" PRIi64 ")", reg_num, reg_offset);
+ s->Printf("DW_OP_bregx(reg=%" PRIu32 ",offset=%" PRIi64 ")", reg_num, reg_offset);
}
break;
case DW_OP_piece: // 0x93 1 ULEB128 size of piece addressed
@@ -664,7 +664,7 @@ DWARFExpression::GetDescription (Stream
if (IsLocationList())
{
// We have a location list
- uint32_t offset = 0;
+ lldb::offset_t offset = 0;
uint32_t count = 0;
addr_t curr_base_addr = location_list_base_addr;
while (m_data.ValidOffset(offset))
@@ -678,7 +678,7 @@ DWARFExpression::GetDescription (Stream
VMRange addr_range(curr_base_addr + begin_addr_offset, curr_base_addr + end_addr_offset);
addr_range.Dump(s, 0, 8);
s->PutChar('{');
- uint32_t location_length = m_data.GetU16(&offset);
+ lldb::offset_t location_length = m_data.GetU16(&offset);
DumpLocation (s, offset, location_length, level, abi);
s->PutChar('}');
offset += location_length;
@@ -782,7 +782,7 @@ ReadRegisterValueAsScalar
//
// if (IsLocationList())
// {
-// uint32_t offset = 0;
+// lldb::offset_t offset = 0;
//
// addr_t loc_list_base_addr = m_loclist_slide.GetLoadAddress(process);
//
@@ -811,10 +811,10 @@ ReadRegisterValueAsScalar
// return false;
//}
-static uint32_t
-GetOpcodeDataSize (const DataExtractor &data, const uint32_t data_offset, const uint8_t op)
+static offset_t
+GetOpcodeDataSize (const DataExtractor &data, const lldb::offset_t data_offset, const uint8_t op)
{
- uint32_t offset = data_offset;
+ lldb::offset_t offset = data_offset;
switch (op)
{
case DW_OP_addr:
@@ -1006,32 +1006,33 @@ GetOpcodeDataSize (const DataExtractor &
default:
break;
}
- return UINT32_MAX;
+ return LLDB_INVALID_OFFSET;
}
-bool
-DWARFExpression::LocationContains_DW_OP_addr (lldb::addr_t file_addr, bool &error) const
+lldb::addr_t
+DWARFExpression::GetLocation_DW_OP_addr (uint32_t op_addr_idx, bool &error) const
{
error = false;
if (IsLocationList())
- return false;
- uint32_t offset = 0;
+ return LLDB_INVALID_ADDRESS;
+ lldb::offset_t offset = 0;
+ uint32_t curr_op_addr_idx = 0;
while (m_data.ValidOffset(offset))
{
const uint8_t op = m_data.GetU8(&offset);
if (op == DW_OP_addr)
{
- if (file_addr == LLDB_INVALID_ADDRESS)
- return true;
- addr_t op_file_addr = m_data.GetAddress(&offset);
- if (op_file_addr == file_addr)
- return true;
+ const lldb::addr_t op_file_addr = m_data.GetAddress(&offset);
+ if (curr_op_addr_idx == op_addr_idx)
+ return op_file_addr;
+ else
+ ++curr_op_addr_idx;
}
else
{
- const uint32_t op_arg_size = GetOpcodeDataSize (m_data, offset, op);
- if (op_arg_size == UINT32_MAX)
+ const offset_t op_arg_size = GetOpcodeDataSize (m_data, offset, op);
+ if (op_arg_size == LLDB_INVALID_OFFSET)
{
error = true;
break;
@@ -1039,7 +1040,7 @@ DWARFExpression::LocationContains_DW_OP_
offset += op_arg_size;
}
}
- return false;
+ return LLDB_INVALID_ADDRESS;
}
bool
@@ -1047,14 +1048,14 @@ DWARFExpression::Update_DW_OP_addr (lldb
{
if (IsLocationList())
return false;
- uint32_t offset = 0;
+ lldb::offset_t offset = 0;
while (m_data.ValidOffset(offset))
{
const uint8_t op = m_data.GetU8(&offset);
if (op == DW_OP_addr)
{
- const uint8_t addr_byte_size = m_data.GetAddressByteSize();
+ const uint32_t addr_byte_size = m_data.GetAddressByteSize();
// We have to make a copy of the data as we don't know if this
// data is from a read only memory mapped buffer, so we duplicate
// all of the data first, then modify it, and if all goes well,
@@ -1083,8 +1084,8 @@ DWARFExpression::Update_DW_OP_addr (lldb
}
else
{
- const uint32_t op_arg_size = GetOpcodeDataSize (m_data, offset, op);
- if (op_arg_size == UINT32_MAX)
+ const offset_t op_arg_size = GetOpcodeDataSize (m_data, offset, op);
+ if (op_arg_size == LLDB_INVALID_OFFSET)
break;
offset += op_arg_size;
}
@@ -1100,7 +1101,7 @@ DWARFExpression::LocationListContainsAdd
if (IsLocationList())
{
- uint32_t offset = 0;
+ lldb::offset_t offset = 0;
if (loclist_base_addr == LLDB_INVALID_ADDRESS)
return false;
@@ -1128,7 +1129,7 @@ DWARFExpression::LocationListContainsAdd
}
bool
-DWARFExpression::GetLocation (addr_t base_addr, addr_t pc, uint32_t &offset, uint32_t &length)
+DWARFExpression::GetLocation (addr_t base_addr, addr_t pc, lldb::offset_t &offset, lldb::offset_t &length)
{
offset = 0;
if (!IsLocationList())
@@ -1164,7 +1165,7 @@ DWARFExpression::GetLocation (addr_t bas
}
}
}
- offset = UINT32_MAX;
+ offset = LLDB_INVALID_OFFSET;
length = 0;
return false;
}
@@ -1176,8 +1177,8 @@ DWARFExpression::DumpLocationForAddress
addr_t address,
ABI *abi)
{
- uint32_t offset = 0;
- uint32_t length = 0;
+ lldb::offset_t offset = 0;
+ lldb::offset_t length = 0;
if (GetLocation (base_addr, address, offset, length))
{
@@ -1223,7 +1224,7 @@ DWARFExpression::Evaluate
{
if (IsLocationList())
{
- uint32_t offset = 0;
+ lldb::offset_t offset = 0;
addr_t pc;
StackFrame *frame = NULL;
if (reg_ctx)
@@ -1294,8 +1295,8 @@ DWARFExpression::Evaluate
ClangExpressionDeclMap *decl_map,
RegisterContext *reg_ctx,
const DataExtractor& opcodes,
- const uint32_t opcodes_offset,
- const uint32_t opcodes_length,
+ const lldb::offset_t opcodes_offset,
+ const lldb::offset_t opcodes_length,
const uint32_t reg_kind,
const Value* initial_value_ptr,
Value& result,
@@ -1318,8 +1319,8 @@ DWARFExpression::Evaluate
if (initial_value_ptr)
stack.push_back(*initial_value_ptr);
- uint32_t offset = opcodes_offset;
- const uint32_t end_offset = opcodes_offset + opcodes_length;
+ lldb::offset_t offset = opcodes_offset;
+ const lldb::offset_t end_offset = opcodes_offset + opcodes_length;
Value tmp;
uint32_t reg_num;
@@ -1330,12 +1331,12 @@ DWARFExpression::Evaluate
error_ptr->SetErrorString ("Invalid offset and/or length for opcodes buffer.");
return false;
}
- LogSP log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS));
+ Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS));
while (opcodes.ValidOffset(offset) && offset < end_offset)
{
- const uint32_t op_offset = offset;
+ const lldb::offset_t op_offset = offset;
const uint8_t op = opcodes.GetU8(&offset);
if (log && log->GetVerbose())
@@ -1349,7 +1350,7 @@ DWARFExpression::Evaluate
stack[i].Dump(&new_value);
log->Printf(" %s", new_value.GetData());
}
- log->Printf("0x%8.8x: %s", op_offset, DW_OP_value_to_name(op));
+ log->Printf("0x%8.8" PRIx64 ": %s", op_offset, DW_OP_value_to_name(op));
}
switch (op)
{
@@ -1431,7 +1432,7 @@ DWARFExpression::Evaluate
if (process->ReadMemory(pointer_addr, &addr_bytes, addr_size, error) == addr_size)
{
DataExtractor addr_data(addr_bytes, sizeof(addr_bytes), process->GetByteOrder(), addr_size);
- uint32_t addr_data_offset = 0;
+ lldb::offset_t addr_data_offset = 0;
stack.back().GetScalar() = addr_data.GetPointer(&addr_data_offset);
stack.back().ClearContext();
}
@@ -1522,7 +1523,7 @@ DWARFExpression::Evaluate
if (process->ReadMemory(pointer_addr, &addr_bytes, size, error) == size)
{
DataExtractor addr_data(addr_bytes, sizeof(addr_bytes), process->GetByteOrder(), size);
- uint32_t addr_data_offset = 0;
+ lldb::offset_t addr_data_offset = 0;
switch (size)
{
case 1: stack.back().GetScalar() = addr_data.GetU8(&addr_data_offset); break;
@@ -1996,7 +1997,7 @@ DWARFExpression::Evaluate
}
else
{
- uint32_t uconst_value = opcodes.GetULEB128(&offset);
+ const uint64_t uconst_value = opcodes.GetULEB128(&offset);
// Implicit conversion from a UINT to a Scalar...
stack.back().ResolveValue(exe_ctx, ast_context) += uconst_value;
if (!stack.back().ResolveValue(exe_ctx, ast_context).IsValid())
@@ -2113,7 +2114,7 @@ DWARFExpression::Evaluate
case DW_OP_skip:
{
int16_t skip_offset = (int16_t)opcodes.GetU16(&offset);
- uint32_t new_offset = offset + skip_offset;
+ lldb::offset_t new_offset = offset + skip_offset;
if (new_offset >= opcodes_offset && new_offset < end_offset)
offset = new_offset;
else
@@ -2143,7 +2144,7 @@ DWARFExpression::Evaluate
Scalar zero(0);
if (tmp.ResolveValue(exe_ctx, ast_context) != zero)
{
- uint32_t new_offset = offset + bra_offset;
+ lldb::offset_t new_offset = offset + bra_offset;
if (new_offset >= opcodes_offset && new_offset < end_offset)
offset = new_offset;
else
@@ -2611,6 +2612,18 @@ DWARFExpression::Evaluate
error_ptr->SetErrorString ("Unimplemented opcode DW_OP_call4.");
return false;
+ //----------------------------------------------------------------------
+ // OPCODE: DW_OP_stack_value
+ // OPERANDS: None
+ // DESCRIPTION: Specifies that the object does not exist in memory but
+ // rather is a constant value. The value from the top of the stack is
+ // the value to be used. This is the actual object value and not the
+ // location.
+ //----------------------------------------------------------------------
+ case DW_OP_stack_value:
+ stack.back().SetValueType(Value::eValueTypeScalar);
+ break;
+
#if 0
//----------------------------------------------------------------------
// OPCODE: DW_OP_call_ref
@@ -2781,7 +2794,7 @@ DWARFExpression::Evaluate
addr_t source_addr = (addr_t)tmp.GetScalar().ULongLong();
addr_t target_addr = (addr_t)stack.back().GetScalar().ULongLong();
- size_t byte_size = (ClangASTType::GetClangTypeBitWidth(ast_context, clang_type) + 7) / 8;
+ const uint64_t byte_size = ClangASTType::GetTypeByteSize(ast_context, clang_type);
switch (source_value_type)
{
Modified: lldb/branches/windows/source/Expression/ExpressionSourceCode.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/windows/source/Expression/ExpressionSourceCode.cpp?rev=179679&r1=179678&r2=179679&view=diff
==============================================================================
--- lldb/branches/windows/source/Expression/ExpressionSourceCode.cpp (original)
+++ lldb/branches/windows/source/Expression/ExpressionSourceCode.cpp Wed Apr 17 03:38:48 2013
@@ -13,18 +13,32 @@
using namespace lldb_private;
-static const char *global_defines = "#undef NULL \n"
- "#undef Nil \n"
- "#undef nil \n"
- "#undef YES \n"
- "#undef NO \n"
- "#define NULL ((int)0) \n"
- "#define Nil ((Class)0) \n"
- "#define nil ((id)0) \n"
- "#define YES ((BOOL)1) \n"
- "#define NO ((BOOL)0) \n"
- "typedef int BOOL; \n"
- "typedef unsigned short unichar; \n";
+const char *
+ExpressionSourceCode::g_expression_prefix =
+"#undef NULL\n"
+"#undef Nil\n"
+"#undef nil\n"
+"#undef YES\n"
+"#undef NO\n"
+"#define NULL (__null)\n"
+"#define Nil (__null)\n"
+"#define nil (__null)\n"
+"#define YES ((BOOL)1)\n"
+"#define NO ((BOOL)0)\n"
+"typedef signed char BOOL;\n"
+"typedef signed __INT8_TYPE__ int8_t;\n"
+"typedef unsigned __INT8_TYPE__ uint8_t;\n"
+"typedef signed __INT16_TYPE__ int16_t;\n"
+"typedef unsigned __INT16_TYPE__ uint16_t;\n"
+"typedef signed __INT32_TYPE__ int32_t;\n"
+"typedef unsigned __INT32_TYPE__ uint32_t;\n"
+"typedef signed __INT64_TYPE__ int64_t;\n"
+"typedef unsigned __INT64_TYPE__ uint64_t;\n"
+"typedef signed __INTPTR_TYPE__ intptr_t;\n"
+"typedef unsigned __INTPTR_TYPE__ uintptr_t;\n"
+"typedef __SIZE_TYPE__ size_t;\n"
+"typedef __PTRDIFF_TYPE__ ptrdiff_t;\n"
+"typedef unsigned short unichar;\n";
bool ExpressionSourceCode::GetText (std::string &text, lldb::LanguageType wrapping_language, bool const_object, bool static_method) const
@@ -56,7 +70,7 @@ bool ExpressionSourceCode::GetText (std:
" %s; \n"
"} \n",
m_prefix.c_str(),
- global_defines,
+ g_expression_prefix,
m_name.c_str(),
m_body.c_str());
break;
@@ -69,7 +83,7 @@ bool ExpressionSourceCode::GetText (std:
" %s; \n"
"} \n",
m_prefix.c_str(),
- global_defines,
+ g_expression_prefix,
m_name.c_str(),
(const_object ? "const" : ""),
m_body.c_str());
@@ -89,7 +103,7 @@ bool ExpressionSourceCode::GetText (std:
"} \n"
"@end \n",
m_prefix.c_str(),
- global_defines,
+ g_expression_prefix,
m_name.c_str(),
m_name.c_str(),
m_body.c_str());
@@ -108,7 +122,7 @@ bool ExpressionSourceCode::GetText (std:
"} \n"
"@end \n",
m_prefix.c_str(),
- global_defines,
+ g_expression_prefix,
m_name.c_str(),
m_name.c_str(),
m_body.c_str());
Modified: lldb/branches/windows/source/Expression/IRDynamicChecks.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/windows/source/Expression/IRDynamicChecks.cpp?rev=179679&r1=179678&r2=179679&view=diff
==============================================================================
--- lldb/branches/windows/source/Expression/IRDynamicChecks.cpp (original)
+++ lldb/branches/windows/source/Expression/IRDynamicChecks.cpp Wed Apr 17 03:38:48 2013
@@ -356,7 +356,7 @@ public:
private:
bool InstrumentInstruction(llvm::Instruction *inst)
{
- lldb::LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
+ Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
if (log)
log->Printf("Instrumenting load/store instruction: %s\n",
@@ -497,7 +497,7 @@ private:
bool InspectInstruction(llvm::Instruction &i)
{
- lldb::LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
+ Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
CallInst *call_inst = dyn_cast<CallInst>(&i);
@@ -604,7 +604,7 @@ IRDynamicChecks::~IRDynamicChecks()
bool
IRDynamicChecks::runOnModule(llvm::Module &M)
{
- lldb::LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
+ Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
llvm::Function* function = M.getFunction(StringRef(m_func_name.c_str()));
Modified: lldb/branches/windows/source/Expression/IRForTarget.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/windows/source/Expression/IRForTarget.cpp?rev=179679&r1=179678&r2=179679&view=diff
==============================================================================
--- lldb/branches/windows/source/Expression/IRForTarget.cpp (original)
+++ lldb/branches/windows/source/Expression/IRForTarget.cpp Wed Apr 17 03:38:48 2013
@@ -22,12 +22,14 @@
#include "clang/AST/ASTContext.h"
-#include "lldb/Core/ConstString.h"
#include "lldb/Core/dwarf.h"
+#include "lldb/Core/ConstString.h"
+#include "lldb/Core/DataBufferHeap.h"
#include "lldb/Core/Log.h"
#include "lldb/Core/Scalar.h"
#include "lldb/Core/StreamString.h"
#include "lldb/Expression/ClangExpressionDeclMap.h"
+#include "lldb/Expression/IRExecutionUnit.h"
#include "lldb/Expression/IRInterpreter.h"
#include "lldb/Host/Endian.h"
#include "lldb/Symbol/ClangASTContext.h"
@@ -38,19 +40,32 @@ using namespace llvm;
static char ID;
-IRForTarget::StaticDataAllocator::StaticDataAllocator()
+IRForTarget::StaticDataAllocator::StaticDataAllocator(lldb_private::IRExecutionUnit &execution_unit) :
+ m_execution_unit(execution_unit),
+ m_allocation(LLDB_INVALID_ADDRESS)
{
}
-IRForTarget::StaticDataAllocator::~StaticDataAllocator()
+lldb::addr_t IRForTarget::StaticDataAllocator::Allocate()
{
+ lldb_private::Error err;
+
+ if (m_allocation != LLDB_INVALID_ADDRESS)
+ {
+ m_execution_unit.FreeNow(m_allocation);
+ m_allocation = LLDB_INVALID_ADDRESS;
+ }
+
+ m_allocation = m_execution_unit.WriteNow((const uint8_t*)m_stream_string.GetData(), m_stream_string.GetSize(), err);
+
+ return m_allocation;
}
IRForTarget::IRForTarget (lldb_private::ClangExpressionDeclMap *decl_map,
bool resolve_vars,
lldb_private::ExecutionPolicy execution_policy,
lldb::ClangExpressionVariableSP &const_result,
- StaticDataAllocator *data_allocator,
+ lldb_private::IRExecutionUnit &execution_unit,
lldb_private::Stream *error_stream,
const char *func_name) :
ModulePass(ID),
@@ -60,7 +75,7 @@ IRForTarget::IRForTarget (lldb_private::
m_func_name(func_name),
m_module(NULL),
m_decl_map(decl_map),
- m_data_allocator(data_allocator),
+ m_data_allocator(execution_unit),
m_CFStringCreateWithBytes(NULL),
m_sel_registerName(NULL),
m_const_result(const_result),
@@ -108,8 +123,6 @@ IRForTarget::~IRForTarget()
bool
IRForTarget::FixFunctionLinkage(llvm::Function &llvm_function)
{
- lldb::LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
-
llvm_function.setLinkage(GlobalValue::ExternalLinkage);
std::string name = llvm_function.getName().str();
@@ -184,7 +197,7 @@ IRForTarget::GetFunctionAddress (llvm::F
lldb_private::ConstString &name,
Constant **&value_ptr)
{
- lldb::LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
+ lldb_private::Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
fun_addr = LLDB_INVALID_ADDRESS;
name.Clear();
@@ -315,8 +328,6 @@ IRForTarget::RegisterFunctionMetadata(LL
llvm::Value *function_ptr,
const char *name)
{
- lldb::LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
-
for (Value::use_iterator i = function_ptr->use_begin(), e = function_ptr->use_end();
i != e;
++i)
@@ -346,7 +357,7 @@ bool
IRForTarget::ResolveFunctionPointers(llvm::Module &llvm_module,
llvm::Function &llvm_function)
{
- lldb::LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
+ lldb_private::Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
for (llvm::Module::iterator fi = llvm_module.begin();
fi != llvm_module.end();
@@ -392,8 +403,6 @@ IRForTarget::ResolveFunctionPointers(llv
clang::NamedDecl *
IRForTarget::DeclForGlobal (const GlobalValue *global_val, Module *module)
{
- lldb::LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
-
NamedMDNode *named_metadata = module->getNamedMetadata("clang.global.decl.ptrs");
if (!named_metadata)
@@ -461,7 +470,7 @@ IRForTarget::MaybeSetConstantResult (llv
void
IRForTarget::MaybeSetCastResult (lldb_private::TypeFromParser type)
{
- lldb::LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
+ lldb_private::Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
if (!m_result_store)
return;
@@ -530,7 +539,7 @@ IRForTarget::MaybeSetCastResult (lldb_pr
bool
IRForTarget::CreateResultVariable (llvm::Function &llvm_function)
{
- lldb::LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
+ lldb_private::Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
if (!m_resolve_vars)
return true;
@@ -709,7 +718,7 @@ IRForTarget::CreateResultVariable (llvm:
m_result_name = m_decl_map->GetPersistentResultName();
if (log)
- log->Printf("Creating a new result global: \"%s\" with size 0x%x",
+ log->Printf("Creating a new result global: \"%s\" with size 0x%" PRIx64,
m_result_name.GetCString(),
m_result_type.GetClangTypeBitWidth() / 8);
@@ -813,7 +822,7 @@ IRForTarget::CreateResultVariable (llvm:
}
#if 0
-static void DebugUsers(lldb::LogSP &log, Value *value, uint8_t depth)
+static void DebugUsers(Log *log, Value *value, uint8_t depth)
{
if (!depth)
return;
@@ -842,7 +851,7 @@ IRForTarget::RewriteObjCConstString (llv
llvm::GlobalVariable *cstr,
Instruction *FirstEntryInstruction)
{
- lldb::LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
+ lldb_private::Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
Type *ns_str_ty = ns_str->getType();
@@ -955,7 +964,7 @@ IRForTarget::RewriteObjCConstString (llv
bool
IRForTarget::RewriteObjCConstStrings(Function &llvm_function)
{
- lldb::LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
+ lldb_private::Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
ValueSymbolTable& value_symbol_table = m_module->getValueSymbolTable();
@@ -1198,7 +1207,7 @@ static bool IsObjCSelectorRef (Value *va
bool
IRForTarget::RewriteObjCSelector (Instruction* selector_load)
{
- lldb::LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
+ lldb_private::Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
LoadInst *load = dyn_cast<LoadInst>(selector_load);
@@ -1314,7 +1323,7 @@ IRForTarget::RewriteObjCSelector (Instru
bool
IRForTarget::RewriteObjCSelectors (BasicBlock &basic_block)
{
- lldb::LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
+ lldb_private::Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
BasicBlock::iterator ii;
@@ -1359,7 +1368,7 @@ IRForTarget::RewriteObjCSelectors (Basic
bool
IRForTarget::RewritePersistentAlloc (llvm::Instruction *persistent_alloc)
{
- lldb::LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
+ lldb_private::Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
AllocaInst *alloc = dyn_cast<AllocaInst>(persistent_alloc);
@@ -1430,7 +1439,7 @@ IRForTarget::RewritePersistentAllocs(llv
if (!m_resolve_vars)
return true;
- lldb::LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
+ lldb_private::Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
BasicBlock::iterator ii;
@@ -1495,7 +1504,7 @@ IRForTarget::MaterializeInitializer (uin
if (!initializer)
return true;
- lldb::LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
+ lldb_private::Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
if (log && log->GetVerbose())
log->Printf(" MaterializeInitializer(%p, %s)", data, PrintValue(initializer).c_str());
@@ -1561,7 +1570,7 @@ IRForTarget::MaterializeInternalVariable
if (global_variable == m_reloc_placeholder)
return true;
- uint64_t offset = m_data_allocator->GetStream().GetSize();
+ uint64_t offset = m_data_allocator.GetStream().GetSize();
llvm::Type *variable_type = global_variable->getType();
@@ -1574,7 +1583,7 @@ IRForTarget::MaterializeInternalVariable
const size_t mask = (align - 1);
uint64_t aligned_offset = (offset + mask) & ~mask;
- m_data_allocator->GetStream().PutNHex8(aligned_offset - offset, 0);
+ m_data_allocator.GetStream().PutNHex8(aligned_offset - offset, 0);
offset = aligned_offset;
lldb_private::DataBufferHeap data(size, '\0');
@@ -1583,7 +1592,7 @@ IRForTarget::MaterializeInternalVariable
if (!MaterializeInitializer(data.GetBytes(), initializer))
return false;
- m_data_allocator->GetStream().Write(data.GetBytes(), data.GetByteSize());
+ m_data_allocator.GetStream().Write(data.GetBytes(), data.GetByteSize());
Constant *new_pointer = BuildRelocation(variable_type, offset);
@@ -1598,7 +1607,7 @@ IRForTarget::MaterializeInternalVariable
bool
IRForTarget::MaybeHandleVariable (Value *llvm_value_ptr)
{
- lldb::LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
+ lldb_private::Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
if (log)
log->Printf("MaybeHandleVariable (%s)", PrintValue(llvm_value_ptr).c_str());
@@ -1676,11 +1685,11 @@ IRForTarget::MaybeHandleVariable (Value
value_type = global_variable->getType();
}
- size_t value_size = (ast_context->getTypeSize(qual_type) + 7) / 8;
- off_t value_alignment = (ast_context->getTypeAlign(qual_type) + 7) / 8;
+ uint64_t value_size = (ast_context->getTypeSize(qual_type) + 7ull) / 8ull;
+ off_t value_alignment = (ast_context->getTypeAlign(qual_type) + 7ull) / 8ull;
if (log)
- log->Printf("Type of \"%s\" is [clang \"%s\", llvm \"%s\"] [size %lu, align %" PRId64 "]",
+ log->Printf("Type of \"%s\" is [clang \"%s\", llvm \"%s\"] [size %" PRIu64 ", align %" PRId64 "]",
name.c_str(),
qual_type.getAsString().c_str(),
PrintType(value_type).c_str(),
@@ -1696,6 +1705,8 @@ IRForTarget::MaybeHandleVariable (Value
{
if (!global_variable->hasExternalLinkage())
return true;
+ else if (HandleSymbol (global_variable))
+ return true;
else
return false;
}
@@ -1715,7 +1726,7 @@ IRForTarget::MaybeHandleVariable (Value
bool
IRForTarget::HandleSymbol (Value *symbol)
{
- lldb::LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
+ lldb_private::Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
lldb_private::ConstString name(symbol->getName().str().c_str());
@@ -1751,7 +1762,7 @@ IRForTarget::HandleSymbol (Value *symbol
bool
IRForTarget::MaybeHandleCallArguments (CallInst *Old)
{
- lldb::LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
+ lldb_private::Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
if (log)
log->Printf("MaybeHandleCallArguments(%s)", PrintValue(Old).c_str());
@@ -1773,7 +1784,7 @@ IRForTarget::MaybeHandleCallArguments (C
bool
IRForTarget::HandleObjCClass(Value *classlist_reference)
{
- lldb::LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
+ lldb_private::Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
GlobalVariable *global_variable = dyn_cast<GlobalVariable>(classlist_reference);
@@ -1801,17 +1812,17 @@ IRForTarget::HandleObjCClass(Value *clas
if (global_variable->use_begin() == global_variable->use_end())
return false;
- LoadInst *load_instruction = NULL;
+ SmallVector<LoadInst *, 2> load_instructions;
for (Value::use_iterator i = global_variable->use_begin(), e = global_variable->use_end();
i != e;
++i)
{
- if ((load_instruction = dyn_cast<LoadInst>(*i)))
- break;
+ if (LoadInst *load_instruction = dyn_cast<LoadInst>(*i))
+ load_instructions.push_back(load_instruction);
}
- if (!load_instruction)
+ if (load_instructions.empty())
return false;
IntegerType *intptr_ty = Type::getIntNTy(m_module->getContext(),
@@ -1819,11 +1830,15 @@ IRForTarget::HandleObjCClass(Value *clas
== Module::Pointer64) ? 64 : 32);
Constant *class_addr = ConstantInt::get(intptr_ty, (uint64_t)class_ptr);
+
+ for (LoadInst *load_instruction : load_instructions)
+ {
Constant *class_bitcast = ConstantExpr::getIntToPtr(class_addr, load_instruction->getType());
load_instruction->replaceAllUsesWith(class_bitcast);
load_instruction->eraseFromParent();
+ }
return true;
}
@@ -1901,7 +1916,7 @@ IRForTarget::ResolveCalls(BasicBlock &ba
bool
IRForTarget::ResolveExternals (Function &llvm_function)
{
- lldb::LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
+ lldb_private::Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
for (Module::global_iterator global = m_module->global_begin(), end = m_module->global_end();
global != end;
@@ -1960,10 +1975,7 @@ IRForTarget::ResolveExternals (Function
bool
IRForTarget::ReplaceStrings ()
{
- lldb::LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
-
- if (!m_data_allocator)
- return true; // hope for the best; some clients may not want static allocation!
+ lldb_private::Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
typedef std::map <GlobalVariable *, size_t> OffsetsTy;
@@ -2016,9 +2028,9 @@ IRForTarget::ReplaceStrings ()
str = gc_array->getAsString();
}
- offsets[gv] = m_data_allocator->GetStream().GetSize();
+ offsets[gv] = m_data_allocator.GetStream().GetSize();
- m_data_allocator->GetStream().Write(str.c_str(), str.length() + 1);
+ m_data_allocator.GetStream().Write(str.c_str(), str.length() + 1);
}
Type *char_ptr_ty = Type::getInt8PtrTy(m_module->getContext());
@@ -2084,11 +2096,8 @@ IRForTarget::ReplaceStrings ()
bool
IRForTarget::ReplaceStaticLiterals (llvm::BasicBlock &basic_block)
{
- lldb::LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
+ lldb_private::Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
- if (!m_data_allocator)
- return true;
-
typedef SmallVector <Value*, 2> ConstantList;
typedef SmallVector <llvm::Instruction*, 2> UserList;
typedef ConstantList::iterator ConstantIterator;
@@ -2158,7 +2167,7 @@ IRForTarget::ReplaceStaticLiterals (llvm
lldb_private::DataBufferHeap data(operand_data_size, 0);
- if (lldb::endian::InlHostByteOrder() != m_data_allocator->GetStream().GetByteOrder())
+ if (lldb::endian::InlHostByteOrder() != m_data_allocator.GetStream().GetByteOrder())
{
uint8_t *data_bytes = data.GetBytes();
@@ -2174,16 +2183,16 @@ IRForTarget::ReplaceStaticLiterals (llvm
memcpy(data.GetBytes(), operand_raw_data, operand_data_size);
}
- uint64_t offset = m_data_allocator->GetStream().GetSize();
+ uint64_t offset = m_data_allocator.GetStream().GetSize();
size_t align = m_target_data->getPrefTypeAlignment(operand_type);
const size_t mask = (align - 1);
uint64_t aligned_offset = (offset + mask) & ~mask;
- m_data_allocator->GetStream().PutNHex8(aligned_offset - offset, 0);
+ m_data_allocator.GetStream().PutNHex8(aligned_offset - offset, 0);
offset = aligned_offset;
- m_data_allocator->GetStream().Write(data.GetBytes(), operand_data_size);
+ m_data_allocator.GetStream().Write(data.GetBytes(), operand_data_size);
llvm::Type *fp_ptr_ty = operand_constant_fp->getType()->getPointerTo();
@@ -2301,7 +2310,7 @@ IRForTarget::RemoveGuards(BasicBlock &ba
bool
IRForTarget::UnfoldConstant(Constant *old_constant, Value *new_constant, Instruction *first_entry_inst)
{
- lldb::LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
+ lldb_private::Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
Value::use_iterator ui;
@@ -2407,7 +2416,7 @@ IRForTarget::ReplaceVariables (Function
if (!m_resolve_vars)
return true;
- lldb::LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
+ lldb_private::Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
m_decl_map->DoStructLayout();
@@ -2581,11 +2590,8 @@ IRForTarget::ReplaceVariables (Function
}
llvm::Constant *
-IRForTarget::BuildRelocation(llvm::Type *type,
- uint64_t offset)
+IRForTarget::BuildRelocation(llvm::Type *type, uint64_t offset)
{
- lldb::LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
-
IntegerType *intptr_ty = Type::getIntNTy(m_module->getContext(),
(m_module->getPointerSize() == Module::Pointer64) ? 64 : 32);
@@ -2605,16 +2611,13 @@ IRForTarget::BuildRelocation(llvm::Type
bool
IRForTarget::CompleteDataAllocation ()
-{
- if (!m_data_allocator)
- return true;
-
- lldb::LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
+{
+ lldb_private::Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
- if (!m_data_allocator->GetStream().GetSize())
+ if (!m_data_allocator.GetStream().GetSize())
return true;
- lldb::addr_t allocation = m_data_allocator->Allocate();
+ lldb::addr_t allocation = m_data_allocator.Allocate();
if (log)
{
@@ -2624,7 +2627,7 @@ IRForTarget::CompleteDataAllocation ()
log->Printf("Failed to allocate static data");
}
- if (!allocation)
+ if (!allocation || allocation == LLDB_INVALID_ADDRESS)
return false;
IntegerType *intptr_ty = Type::getIntNTy(m_module->getContext(),
@@ -2643,7 +2646,7 @@ IRForTarget::CompleteDataAllocation ()
bool
IRForTarget::StripAllGVs (Module &llvm_module)
{
- lldb::LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
+ lldb_private::Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
std::vector<GlobalVariable *> global_vars;
std::set<GlobalVariable *>erased_vars;
@@ -2693,7 +2696,7 @@ IRForTarget::StripAllGVs (Module &llvm_m
bool
IRForTarget::runOnModule (Module &llvm_module)
{
- lldb::LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
+ lldb_private::Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
m_module = &llvm_module;
m_target_data.reset(new DataLayout(m_module));
Modified: lldb/branches/windows/source/Expression/IRInterpreter.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/windows/source/Expression/IRInterpreter.cpp?rev=179679&r1=179678&r2=179679&view=diff
==============================================================================
--- lldb/branches/windows/source/Expression/IRInterpreter.cpp (original)
+++ lldb/branches/windows/source/Expression/IRInterpreter.cpp Wed Apr 17 03:38:48 2013
@@ -506,7 +506,7 @@ public:
size_t value_size = m_target_data.getTypeStoreSize(value->getType());
- uint32_t offset = 0;
+ lldb::offset_t offset = 0;
uint64_t u64value = value_extractor->GetMaxU64(&offset, value_size);
return AssignToMatchType(scalar, u64value, value->getType());
@@ -524,7 +524,7 @@ public:
if (!AssignToMatchType(cast_scalar, scalar.GetRawBits64(0), value->getType()))
return false;
- lldb_private::DataBufferHeap buf(cast_scalar.GetByteSize(), 0);
+ lldb_private::DataBufferHeap buf(region.m_extent, 0);
lldb_private::Error err;
@@ -533,6 +533,9 @@ public:
DataEncoderSP region_encoder = m_memory.GetEncoder(region);
+ if (buf.GetByteSize() > region_encoder->GetByteSize())
+ return false; // This should not happen
+
memcpy(region_encoder->GetDataStart(), buf.GetBytes(), buf.GetByteSize());
return true;
@@ -621,6 +624,11 @@ public:
// "this", "self", and "_cmd" are direct.
bool variable_is_this = false;
+ // If the variable is a function pointer, we do not need to
+ // build an extra layer of indirection for it because it is
+ // accessed directly.
+ bool variable_is_function_address = false;
+
// Attempt to resolve the value using the program's data.
// If it is, the values to be created are:
//
@@ -631,7 +639,7 @@ public:
// resides. This is an IR-level variable.
do
{
- lldb::LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
+ lldb_private::Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
lldb_private::Value resolved_value;
lldb_private::ClangExpressionVariable::FlagType flags = 0;
@@ -644,13 +652,8 @@ public:
break;
if (isa<clang::FunctionDecl>(decl))
- {
- if (log)
- log->Printf("The interpreter does not handle function pointers at the moment");
+ variable_is_function_address = true;
- return Memory::Region();
- }
-
resolved_value = m_decl_map.LookupDecl(decl, flags);
}
else
@@ -662,10 +665,11 @@ public:
if (name_str == "this" ||
name_str == "self" ||
name_str == "_cmd")
+ {
resolved_value = m_decl_map.GetSpecialValue(lldb_private::ConstString(name_str.c_str()));
-
variable_is_this = true;
}
+ }
if (resolved_value.GetScalar().GetType() != lldb_private::Scalar::e_void)
{
@@ -782,17 +786,19 @@ public:
}
else
{
+ bool no_extra_redirect = (variable_is_this || variable_is_function_address);
+
Memory::Region data_region = m_memory.Place(value->getType(), resolved_value.GetScalar().ULongLong(), resolved_value);
Memory::Region ref_region = m_memory.Malloc(value->getType());
Memory::Region pointer_region;
- if (!variable_is_this)
+ if (!no_extra_redirect)
pointer_region = m_memory.Malloc(value->getType());
if (ref_region.IsInvalid())
return Memory::Region();
- if (pointer_region.IsInvalid() && !variable_is_this)
+ if (pointer_region.IsInvalid() && !no_extra_redirect)
return Memory::Region();
DataEncoderSP ref_encoder = m_memory.GetEncoder(ref_region);
@@ -800,7 +806,7 @@ public:
if (ref_encoder->PutAddress(0, data_region.m_base) == UINT32_MAX)
return Memory::Region();
- if (!variable_is_this)
+ if (!no_extra_redirect)
{
DataEncoderSP pointer_encoder = m_memory.GetEncoder(pointer_region);
@@ -820,7 +826,7 @@ public:
log->Printf(" Pointer region : %llx", (unsigned long long)pointer_region.m_base);
}
- if (variable_is_this)
+ if (no_extra_redirect)
return ref_region;
else
return pointer_region;
@@ -833,8 +839,6 @@ public:
Type *type = value->getType();
- lldb::ValueSP backing_value(new lldb_private::Value);
-
Memory::Region data_region = m_memory.Malloc(type);
data_region.m_allocation->m_origin.GetScalar() = (unsigned long long)data_region.m_allocation->m_data->GetBytes();
data_region.m_allocation->m_origin.SetContext(lldb_private::Value::eContextTypeInvalid, NULL);
@@ -885,7 +889,7 @@ public:
return false;
Type *R_ty = pointer_ptr_ty->getElementType();
- uint32_t offset = 0;
+ lldb::offset_t offset = 0;
lldb::addr_t pointer = P_extractor->GetAddress(&offset);
Memory::Region R = m_memory.Lookup(pointer, R_ty);
@@ -980,7 +984,7 @@ bool
IRInterpreter::supportsFunction (Function &llvm_function,
lldb_private::Error &err)
{
- lldb::LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
+ lldb_private::Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
for (Function::iterator bbi = llvm_function.begin(), bbe = llvm_function.end();
bbi != bbe;
@@ -1042,17 +1046,23 @@ IRInterpreter::supportsFunction (Functio
}
}
break;
+ case Instruction::And:
+ case Instruction::AShr:
case Instruction::IntToPtr:
case Instruction::PtrToInt:
case Instruction::Load:
+ case Instruction::LShr:
case Instruction::Mul:
+ case Instruction::Or:
case Instruction::Ret:
case Instruction::SDiv:
+ case Instruction::Shl:
case Instruction::SRem:
case Instruction::Store:
case Instruction::Sub:
case Instruction::UDiv:
case Instruction::URem:
+ case Instruction::Xor:
case Instruction::ZExt:
break;
}
@@ -1076,7 +1086,7 @@ IRInterpreter::runOnFunction (lldb::Clan
Module &llvm_module,
lldb_private::Error &err)
{
- lldb::LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
+ lldb_private::Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
lldb_private::ClangExpressionDeclMap::TargetInfo target_info = m_decl_map.GetTargetInfo();
@@ -1145,6 +1155,12 @@ IRInterpreter::runOnFunction (lldb::Clan
case Instruction::UDiv:
case Instruction::SRem:
case Instruction::URem:
+ case Instruction::Shl:
+ case Instruction::LShr:
+ case Instruction::AShr:
+ case Instruction::And:
+ case Instruction::Or:
+ case Instruction::Xor:
{
const BinaryOperator *bin_op = dyn_cast<BinaryOperator>(inst);
@@ -1208,6 +1224,25 @@ IRInterpreter::runOnFunction (lldb::Clan
case Instruction::URem:
result = L.GetRawBits64(0) % R.GetRawBits64(1);
break;
+ case Instruction::Shl:
+ result = L << R;
+ break;
+ case Instruction::AShr:
+ result = L >> R;
+ break;
+ case Instruction::LShr:
+ result = L;
+ result.ShiftRightLogical(R);
+ break;
+ case Instruction::And:
+ result = L & R;
+ break;
+ case Instruction::Or:
+ result = L | R;
+ break;
+ case Instruction::Xor:
+ result = L ^ R;
+ break;
}
frame.AssignValue(inst, result, llvm_module);
@@ -1668,7 +1703,7 @@ IRInterpreter::runOnFunction (lldb::Clan
DataExtractorSP P_extractor(memory.GetExtractor(P));
DataEncoderSP D_encoder(memory.GetEncoder(D));
- uint32_t offset = 0;
+ lldb::offset_t offset = 0;
lldb::addr_t pointer = P_extractor->GetAddress(&offset);
Memory::Region R = memory.Lookup(pointer, target_ty);
@@ -1781,7 +1816,7 @@ IRInterpreter::runOnFunction (lldb::Clan
if (!P_extractor || !D_extractor)
return false;
- uint32_t offset = 0;
+ lldb::offset_t offset = 0;
lldb::addr_t pointer = P_extractor->GetAddress(&offset);
Memory::Region R = memory.Lookup(pointer, target_ty);
Removed: lldb/branches/windows/source/Expression/ProcessDataAllocator.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/windows/source/Expression/ProcessDataAllocator.cpp?rev=179678&view=auto
==============================================================================
--- lldb/branches/windows/source/Expression/ProcessDataAllocator.cpp (original)
+++ lldb/branches/windows/source/Expression/ProcessDataAllocator.cpp (removed)
@@ -1,43 +0,0 @@
-//===-- ProcessDataAllocator.cpp --------------------------------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-#include "lldb/Core/DataBufferHeap.h"
-#include "lldb/Core/DataExtractor.h"
-#include "lldb/Expression/ProcessDataAllocator.h"
-
-using namespace lldb_private;
-
-void
-ProcessDataAllocator::Dump(Stream &stream)
-{
- size_t data_size = m_stream_string.GetSize();
-
- if (!m_allocation)
- return;
-
- lldb::DataBufferSP data(new DataBufferHeap(data_size, 0));
-
- Error error;
- if (m_process.ReadMemory (m_allocation, data->GetBytes(), data_size, error) != data_size)
- return;
-
- DataExtractor extractor(data, m_process.GetByteOrder(), m_process.GetAddressByteSize());
-
- extractor.Dump(&stream, // stream
- 0, // offset
- lldb::eFormatBytesWithASCII, // format
- 1, // byte size of individual entries
- data_size, // number of entries
- 16, // entries per line
- m_allocation, // address to print
- 0, // bit size (bitfields only; 0 means ignore)
- 0); // bit alignment (bitfields only; 0 means ignore)
-
- stream.PutChar('\n');
-}
Removed: lldb/branches/windows/source/Expression/RecordingMemoryManager.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/windows/source/Expression/RecordingMemoryManager.cpp?rev=179678&view=auto
==============================================================================
--- lldb/branches/windows/source/Expression/RecordingMemoryManager.cpp (original)
+++ lldb/branches/windows/source/Expression/RecordingMemoryManager.cpp (removed)
@@ -1,340 +0,0 @@
-//===-- RecordingMemoryManager.cpp ------------------------------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-
-// C Includes
-// C++ Includes
-// Other libraries and framework includes
-#include "llvm/ExecutionEngine/ExecutionEngine.h"
-// Project includes
-#include "lldb/Expression/RecordingMemoryManager.h"
-
-using namespace lldb_private;
-
-RecordingMemoryManager::RecordingMemoryManager () :
- llvm::JITMemoryManager(),
- m_default_mm_ap (llvm::JITMemoryManager::CreateDefaultMemManager()),
- m_log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS))
-{
-}
-
-RecordingMemoryManager::~RecordingMemoryManager ()
-{
-}
-
-void
-RecordingMemoryManager::setMemoryWritable ()
-{
- m_default_mm_ap->setMemoryWritable();
-}
-
-void
-RecordingMemoryManager::setMemoryExecutable ()
-{
- m_default_mm_ap->setMemoryExecutable();
-}
-
-
-uint8_t *
-RecordingMemoryManager::startFunctionBody(const llvm::Function *F,
- uintptr_t &ActualSize)
-{
- return m_default_mm_ap->startFunctionBody(F, ActualSize);
-}
-
-uint8_t *
-RecordingMemoryManager::allocateStub(const llvm::GlobalValue* F, unsigned StubSize,
- unsigned Alignment)
-{
- uint8_t *return_value = m_default_mm_ap->allocateStub(F, StubSize, Alignment);
-
- Allocation allocation;
- allocation.m_size = StubSize;
- allocation.m_alignment = Alignment;
- allocation.m_local_start = (uintptr_t)return_value;
-
- if (m_log)
- {
- m_log->Printf("RecordingMemoryManager::allocateStub (F=%p, StubSize=%u, Alignment=%u) = %p",
- F, StubSize, Alignment, return_value);
- allocation.dump(m_log);
- }
-
- m_allocations.push_back(allocation);
-
- return return_value;
-}
-
-void
-RecordingMemoryManager::endFunctionBody(const llvm::Function *F, uint8_t *FunctionStart,
- uint8_t *FunctionEnd)
-{
- m_default_mm_ap->endFunctionBody(F, FunctionStart, FunctionEnd);
-}
-
-uint8_t *
-RecordingMemoryManager::allocateSpace(intptr_t Size, unsigned Alignment)
-{
- uint8_t *return_value = m_default_mm_ap->allocateSpace(Size, Alignment);
-
- Allocation allocation;
- allocation.m_size = Size;
- allocation.m_alignment = Alignment;
- allocation.m_local_start = (uintptr_t)return_value;
-
- if (m_log)
- {
- m_log->Printf("RecordingMemoryManager::allocateSpace(Size=%" PRIu64 ", Alignment=%u) = %p",
- (uint64_t)Size, Alignment, return_value);
- allocation.dump(m_log);
- }
-
- m_allocations.push_back(allocation);
-
- return return_value;
-}
-
-uint8_t *
-RecordingMemoryManager::allocateCodeSection(uintptr_t Size, unsigned Alignment, unsigned SectionID)
-{
- uint8_t *return_value = m_default_mm_ap->allocateCodeSection(Size, Alignment, SectionID);
-
- Allocation allocation;
- allocation.m_size = Size;
- allocation.m_alignment = Alignment;
- allocation.m_local_start = (uintptr_t)return_value;
- allocation.m_section_id = SectionID;
- allocation.m_executable = true;
-
- if (m_log)
- {
- m_log->Printf("RecordingMemoryManager::allocateCodeSection(Size=0x%" PRIx64 ", Alignment=%u, SectionID=%u) = %p",
- (uint64_t)Size, Alignment, SectionID, return_value);
- allocation.dump(m_log);
- }
-
- m_allocations.push_back(allocation);
-
- return return_value;
-}
-
-uint8_t *
-RecordingMemoryManager::allocateDataSection(uintptr_t Size, unsigned Alignment, unsigned SectionID, bool IsReadOnly)
-{
- uint8_t *return_value = m_default_mm_ap->allocateDataSection(Size, Alignment, SectionID, IsReadOnly);
-
- Allocation allocation;
- allocation.m_size = Size;
- allocation.m_alignment = Alignment;
- allocation.m_local_start = (uintptr_t)return_value;
- allocation.m_section_id = SectionID;
-
- if (m_log)
- {
- m_log->Printf("RecordingMemoryManager::allocateDataSection(Size=0x%" PRIx64 ", Alignment=%u, SectionID=%u) = %p",
- (uint64_t)Size, Alignment, SectionID, return_value);
- allocation.dump(m_log);
- }
-
- m_allocations.push_back(allocation);
-
- return return_value;
-}
-
-uint8_t *
-RecordingMemoryManager::allocateGlobal(uintptr_t Size, unsigned Alignment)
-{
- uint8_t *return_value = m_default_mm_ap->allocateGlobal(Size, Alignment);
-
- Allocation allocation;
- allocation.m_size = Size;
- allocation.m_alignment = Alignment;
- allocation.m_local_start = (uintptr_t)return_value;
-
- if (m_log)
- {
- m_log->Printf("RecordingMemoryManager::allocateGlobal(Size=0x%" PRIx64 ", Alignment=%u) = %p",
- (uint64_t)Size, Alignment, return_value);
- allocation.dump(m_log);
- }
-
- m_allocations.push_back(allocation);
-
- return return_value;
-}
-
-void
-RecordingMemoryManager::deallocateFunctionBody(void *Body)
-{
- m_default_mm_ap->deallocateFunctionBody(Body);
-}
-
-uint8_t*
-RecordingMemoryManager::startExceptionTable(const llvm::Function* F,
- uintptr_t &ActualSize)
-{
- return m_default_mm_ap->startExceptionTable(F, ActualSize);
-}
-
-void
-RecordingMemoryManager::endExceptionTable(const llvm::Function *F, uint8_t *TableStart,
- uint8_t *TableEnd, uint8_t* FrameRegister)
-{
- m_default_mm_ap->endExceptionTable(F, TableStart, TableEnd, FrameRegister);
-}
-
-void
-RecordingMemoryManager::deallocateExceptionTable(void *ET)
-{
- m_default_mm_ap->deallocateExceptionTable (ET);
-}
-
-lldb::addr_t
-RecordingMemoryManager::GetRemoteAddressForLocal (lldb::addr_t local_address)
-{
- for (AllocationList::iterator ai = m_allocations.begin(), ae = m_allocations.end();
- ai != ae;
- ++ai)
- {
- if (local_address >= ai->m_local_start &&
- local_address < ai->m_local_start + ai->m_size)
- return ai->m_remote_start + (local_address - ai->m_local_start);
- }
-
- return LLDB_INVALID_ADDRESS;
-}
-
-RecordingMemoryManager::AddrRange
-RecordingMemoryManager::GetRemoteRangeForLocal (lldb::addr_t local_address)
-{
- for (AllocationList::iterator ai = m_allocations.begin(), ae = m_allocations.end();
- ai != ae;
- ++ai)
- {
- if (local_address >= ai->m_local_start &&
- local_address < ai->m_local_start + ai->m_size)
- return AddrRange(ai->m_remote_start, ai->m_size);
- }
-
- return AddrRange (0, 0);
-}
-
-bool
-RecordingMemoryManager::CommitAllocations (Process &process)
-{
- bool ret = true;
-
- for (AllocationList::iterator ai = m_allocations.begin(), ae = m_allocations.end();
- ai != ae;
- ++ai)
- {
- if (ai->m_allocated)
- continue;
-
- lldb_private::Error err;
-
- size_t allocation_size = (ai->m_size ? ai->m_size : 1) + ai->m_alignment - 1;
-
- if (allocation_size == 0)
- allocation_size = 1;
-
- ai->m_remote_allocation = process.AllocateMemory(
- allocation_size,
- ai->m_executable ? (lldb::ePermissionsReadable | lldb::ePermissionsExecutable)
- : (lldb::ePermissionsReadable | lldb::ePermissionsWritable),
- err);
-
- uint64_t mask = ai->m_alignment - 1;
-
- ai->m_remote_start = (ai->m_remote_allocation + mask) & (~mask);
-
- if (!err.Success())
- {
- ret = false;
- break;
- }
-
- ai->m_allocated = true;
-
- if (m_log)
- {
- m_log->Printf("RecordingMemoryManager::CommitAllocations() committed an allocation");
- ai->dump(m_log);
- }
- }
-
- if (!ret)
- {
- for (AllocationList::iterator ai = m_allocations.end(), ae = m_allocations.end();
- ai != ae;
- ++ai)
- {
- if (ai->m_allocated)
- process.DeallocateMemory(ai->m_remote_start);
- }
- }
-
- return ret;
-}
-
-void
-RecordingMemoryManager::ReportAllocations (llvm::ExecutionEngine &engine)
-{
- for (AllocationList::iterator ai = m_allocations.begin(), ae = m_allocations.end();
- ai != ae;
- ++ai)
- {
- if (!ai->m_allocated)
- continue;
-
- engine.mapSectionAddress((void*)ai->m_local_start, ai->m_remote_start);
- }
-}
-
-bool
-RecordingMemoryManager::WriteData (Process &process)
-{
- for (AllocationList::iterator ai = m_allocations.begin(), ae = m_allocations.end();
- ai != ae;
- ++ai)
- {
- if (!ai->m_allocated)
- return false;
-
- lldb_private::Error err;
-
- if (process.WriteMemory(ai->m_remote_start,
- (void*)ai->m_local_start,
- ai->m_size,
- err) != ai->m_size ||
- !err.Success())
- return false;
-
- if (m_log)
- {
- m_log->Printf("RecordingMemoryManager::CommitAllocations() wrote an allocation");
- ai->dump(m_log);
- }
- }
-
- return true;
-}
-
-void
-RecordingMemoryManager::Allocation::dump (lldb::LogSP log)
-{
- if (!log)
- return;
-
- log->Printf("[0x%llx+0x%llx]->0x%llx (alignment %d, section ID %d)",
- (unsigned long long)m_local_start,
- (unsigned long long)m_size,
- (unsigned long long)m_remote_start,
- (unsigned)m_alignment,
- (unsigned)m_section_id);
-}
Modified: lldb/branches/windows/source/Host/CMakeLists.txt
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/windows/source/Host/CMakeLists.txt?rev=179679&r1=179678&r2=179679&view=diff
==============================================================================
--- lldb/branches/windows/source/Host/CMakeLists.txt (original)
+++ lldb/branches/windows/source/Host/CMakeLists.txt Wed Apr 17 03:38:48 2013
@@ -1,3 +1,3 @@
add_subdirectory(common)
-#add_subdirectory(linux)
+add_subdirectory(linux)
add_subdirectory(windows)
Modified: lldb/branches/windows/source/Host/common/File.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/windows/source/Host/common/File.cpp?rev=179679&r1=179678&r2=179679&view=diff
==============================================================================
--- lldb/branches/windows/source/Host/common/File.cpp (original)
+++ lldb/branches/windows/source/Host/common/File.cpp Wed Apr 17 03:38:48 2013
@@ -665,12 +665,12 @@ File::Write (const void *buf, size_t &nu
//------------------------------------------------------------------
// Print some formatted output to the stream.
//------------------------------------------------------------------
-int
+size_t
File::Printf (const char *format, ...)
{
va_list args;
va_start (args, format);
- int result = PrintfVarArg (format, args);
+ size_t result = PrintfVarArg (format, args);
va_end (args);
return result;
}
@@ -678,10 +678,10 @@ File::Printf (const char *format, ...)
//------------------------------------------------------------------
// Print some formatted output to the stream.
//------------------------------------------------------------------
-int
+size_t
File::PrintfVarArg (const char *format, va_list args)
{
- int result = 0;
+ size_t result = 0;
if (DescriptorIsValid())
{
char *s = NULL;
Modified: lldb/branches/windows/source/Host/common/FileSpec.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/windows/source/Host/common/FileSpec.cpp?rev=179679&r1=179678&r2=179679&view=diff
==============================================================================
--- lldb/branches/windows/source/Host/common/FileSpec.cpp (original)
+++ lldb/branches/windows/source/Host/common/FileSpec.cpp Wed Apr 17 03:38:48 2013
@@ -121,7 +121,7 @@ FileSpec::ResolveUsername (const char *s
}
else
{
- int user_name_len = first_slash - src_path - 1;
+ size_t user_name_len = first_slash - src_path - 1;
::memcpy (user_home, src_path + 1, user_name_len);
user_home[user_name_len] = '\0';
user_name = user_home;
@@ -913,8 +913,23 @@ FileSpec::EnumerateDirectory
lldb_utility::CleanUp <DIR *, int> dir_path_dir (opendir(dir_path), NULL, closedir);
if (dir_path_dir.is_valid())
{
- struct dirent* dp;
- while ((dp = readdir(dir_path_dir.get())) != NULL)
+
+#if _WIN32
+ long path_max = MAX_PATH;
+#else
+ long path_max = fpathconf (dirfd (dir_path_dir.get()), _PC_NAME_MAX);
+#if defined (__APPLE_) && defined (__DARWIN_MAXPATHLEN)
+ if (path_max < __DARWIN_MAXPATHLEN)
+ path_max = __DARWIN_MAXPATHLEN;
+#endif
+#endif
+ struct dirent *buf, *dp;
+ buf = (struct dirent *) malloc (offsetof (struct dirent, d_name) + path_max + 1);
+#if _WIN32
+ while (dp = readdir(dir_path_dir.get()))
+#else
+ while (buf && readdir_r(dir_path_dir.get(), buf, &dp) == 0 && dp)
+#endif
{
// Only search directories
if (dp->d_type == DT_DIR || dp->d_type == DT_UNKNOWN)
@@ -993,8 +1008,12 @@ FileSpec::EnumerateDirectory
}
}
}
+ if (buf)
+ {
+ free (buf);
}
}
+ }
// By default when exiting a directory, we tell the parent enumeration
// to continue enumerating.
return eEnumerateDirectoryResultNext;
@@ -1015,8 +1034,7 @@ FileSpec::IsSourceImplementationFile ()
ConstString extension (GetFileNameExtension());
if (extension)
{
- static RegularExpression g_source_file_regex ("^(c|m|mm|cpp|c\\+\\+|cxx|cc|cp|s|asm|f|f77|f90|f95|f03|for|ftn|fpp|ada|adb|ads)$",
- llvm::Regex::IgnoreCase);
+ static RegularExpression g_source_file_regex ("^(c|m|mm|cpp|c\\+\\+|cxx|cc|cp|s|asm|f|f77|f90|f95|f03|for|ftn|fpp|ada|adb|ads)$", 1); // IgnorCase
return g_source_file_regex.Execute (extension.GetCString());
}
return false;
Modified: lldb/branches/windows/source/Host/common/Host.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/windows/source/Host/common/Host.cpp?rev=179679&r1=179678&r2=179679&view=diff
==============================================================================
--- lldb/branches/windows/source/Host/common/Host.cpp (original)
+++ lldb/branches/windows/source/Host/common/Host.cpp Wed Apr 17 03:38:48 2013
@@ -9,25 +9,7 @@
#include "lldb/lldb-python.h"
-#include "lldb/Host/Host.h"
-#include "lldb/Core/ArchSpec.h"
-#include "lldb/Core/ConstString.h"
-#include "lldb/Core/Debugger.h"
-#include "lldb/Core/Error.h"
-#include "lldb/Core/Log.h"
-#include "lldb/Core/StreamString.h"
-#include "lldb/Core/ThreadSafeSTLMap.h"
-#include "lldb/Host/Config.h"
-#include "lldb/Host/Endian.h"
-#include "lldb/Host/FileSpec.h"
-#include "lldb/Host/Mutex.h"
-#include "lldb/Target/Process.h"
-#include "lldb/Target/TargetList.h"
-
-#include "llvm/Support/Host.h"
-#include "llvm/Support/MachO.h"
-#include "llvm/ADT/Twine.h"
-
+// C includes
#include <errno.h>
#include <limits.h>
@@ -36,9 +18,10 @@
#include <grp.h>
#include <netdb.h>
#include <pwd.h>
-#endif
-
+#include <sys/sysctl.h>
+#include <unistd.h>
#include <sys/types.h>
+#endif
#if defined (__APPLE__)
@@ -46,8 +29,6 @@
#include <libproc.h>
#include <mach-o/dyld.h>
#include <mach/mach_port.h>
-#include <sys/sysctl.h>
-
#elif defined (__linux__)
@@ -56,11 +37,33 @@
#elif defined (__FreeBSD__)
#include <sys/wait.h>
-#include <sys/sysctl.h>
#include <pthread_np.h>
#endif
+#include "lldb/Host/Host.h"
+#include "lldb/Core/ArchSpec.h"
+#include "lldb/Core/ConstString.h"
+#include "lldb/Core/Debugger.h"
+#include "lldb/Core/Error.h"
+#include "lldb/Core/Log.h"
+#include "lldb/Core/StreamString.h"
+#include "lldb/Core/ThreadSafeSTLMap.h"
+#include "lldb/Host/Config.h"
+#include "lldb/Host/Endian.h"
+#include "lldb/Host/FileSpec.h"
+#include "lldb/Host/Mutex.h"
+#include "lldb/Target/Process.h"
+#include "lldb/Target/TargetList.h"
+
+#include "llvm/Support/Host.h"
+#include "llvm/Support/MachO.h"
+#include "llvm/ADT/Twine.h"
+
+
+
+
+
using namespace lldb;
using namespace lldb_private;
@@ -136,7 +139,7 @@ private:
static thread_result_t
MonitorChildProcessThreadFunction (void *arg)
{
- LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_PROCESS));
+ Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_PROCESS));
const char *function = __FUNCTION__;
if (log)
log->Printf ("%s (arg = %p) thread starting...", function, arg);
@@ -151,7 +154,7 @@ MonitorChildProcessThreadFunction (void
delete info;
int status = -1;
- const int options = 0;
+ const int options = __WALL;
#ifndef _WIN32
while (1)
@@ -162,7 +165,8 @@ MonitorChildProcessThreadFunction (void
// Wait for all child processes
::pthread_testcancel ();
- const lldb::pid_t wait_pid = ::waitpid (pid, &status, options);
+ // Get signals from all children with same process group of pid
+ const lldb::pid_t wait_pid = ::waitpid (-1*pid, &status, options);
::pthread_testcancel ();
if (wait_pid == -1)
@@ -172,7 +176,7 @@ MonitorChildProcessThreadFunction (void
else
break;
}
- else if (wait_pid == pid)
+ else if (wait_pid > 0)
{
bool exited = false;
int signal = 0;
@@ -187,14 +191,17 @@ MonitorChildProcessThreadFunction (void
{
exit_status = WEXITSTATUS(status);
status_cstr = "EXITED";
- exited = true;
+ if (wait_pid == pid)
+ exited = true;
}
else if (WIFSIGNALED(status))
{
signal = WTERMSIG(status);
status_cstr = "SIGNALED";
- exited = true;
- exit_status = -1;
+ if (wait_pid == pid) {
+ exited = true;
+ exit_status = -1;
+ }
}
else
{
@@ -221,7 +228,7 @@ MonitorChildProcessThreadFunction (void
{
bool callback_return = false;
if (callback)
- callback_return = callback (callback_baton, pid, exited, signal, exit_status);
+ callback_return = callback (callback_baton, wait_pid, exited, signal, exit_status);
// If our process exited, then this thread should exit
if (exited)
@@ -576,7 +583,7 @@ ThreadCreateTrampoline (thread_arg_t arg
thread_func_t thread_fptr = info->thread_fptr;
thread_arg_t thread_arg = info->thread_arg;
- LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_THREAD));
+ Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_THREAD));
if (log)
log->Printf("thread created");
@@ -658,101 +665,44 @@ Host::ThreadJoin (lldb::thread_t thread,
#endif
}
-// rdar://problem/8153284
-// Fixed a crasher where during shutdown, loggings attempted to access the
-// thread name but the static map instance had already been destructed.
-// So we are using a ThreadSafeSTLMap POINTER, initializing it with a
-// pthread_once action. That map will get leaked.
-//
-// Another approach is to introduce a static guard object which monitors its
-// own destruction and raises a flag, but this incurs more overhead.
-#ifndef _WIN32
-static pthread_once_t g_thread_map_once = PTHREAD_ONCE_INIT;
-#else
-static unsigned int g_thread_map_once = 0;
-#endif
-static ThreadSafeSTLMap<uint64_t, std::string> *g_thread_names_map_ptr;
-
-static void
-InitThreadNamesMap()
-{
- g_thread_names_map_ptr = new ThreadSafeSTLMap<uint64_t, std::string>();
-}
-
-//------------------------------------------------------------------
-// Control access to a static file thread name map using a single
-// static function to avoid a static constructor.
-//------------------------------------------------------------------
-static const char *
-ThreadNameAccessor (bool get, lldb::pid_t pid, lldb::tid_t tid, const char *name)
-{
-#ifndef _WIN32
- int success = ::pthread_once (&g_thread_map_once, InitThreadNamesMap);
- if (success != 0)
- return NULL;
-#else
- if (InterlockedExchange(&g_thread_map_once, 1) == 0)
- InitThreadNamesMap();
-#endif
-
- uint64_t pid_tid = ((uint64_t)pid << 32) | (uint64_t)tid;
-
- if (get)
- {
- // See if the thread name exists in our thread name pool
- std::string value;
- bool found_it = g_thread_names_map_ptr->GetValueForKey (pid_tid, value);
- if (found_it)
- return value.c_str();
- else
- return NULL;
- }
- else if (name)
- {
- // Set the thread name
- g_thread_names_map_ptr->SetValueForKey (pid_tid, std::string(name));
- }
- return NULL;
-}
-
-const char *
+std::string
Host::GetThreadName (lldb::pid_t pid, lldb::tid_t tid)
{
- const char *name = ThreadNameAccessor (true, pid, tid, NULL);
- if (name == NULL)
- {
+ std::string thread_name;
#if defined(__APPLE__) && MAC_OS_X_VERSION_MAX_ALLOWED > MAC_OS_X_VERSION_10_5
- // We currently can only get the name of a thread in the current process.
- if (pid == Host::GetCurrentProcessID())
+ // We currently can only get the name of a thread in the current process.
+ if (pid == Host::GetCurrentProcessID())
+ {
+ char pthread_name[1024];
+ if (::pthread_getname_np (::pthread_from_mach_thread_np (tid), pthread_name, sizeof(pthread_name)) == 0)
{
- char pthread_name[1024];
- if (::pthread_getname_np (::pthread_from_mach_thread_np (tid), pthread_name, sizeof(pthread_name)) == 0)
+ if (pthread_name[0])
{
- if (pthread_name[0])
- {
- // Set the thread in our string pool
- ThreadNameAccessor (false, pid, tid, pthread_name);
- // Get our copy of the thread name string
- name = ThreadNameAccessor (true, pid, tid, NULL);
- }
+ thread_name = pthread_name;
}
-
- if (name == NULL)
+ }
+ else
+ {
+ dispatch_queue_t current_queue = ::dispatch_get_current_queue ();
+ if (current_queue != NULL)
{
- dispatch_queue_t current_queue = ::dispatch_get_current_queue ();
- if (current_queue != NULL)
- name = dispatch_queue_get_label (current_queue);
+ const char *queue_name = dispatch_queue_get_label (current_queue);
+ if (queue_name && queue_name[0])
+ {
+ thread_name = queue_name;
+ }
}
}
-#endif
}
- return name;
+#endif
+ return thread_name;
}
void
Host::SetThreadName (lldb::pid_t pid, lldb::tid_t tid, const char *name)
{
+#if defined(__APPLE__) && MAC_OS_X_VERSION_MAX_ALLOWED > MAC_OS_X_VERSION_10_5
lldb::pid_t curr_pid = Host::GetCurrentProcessID();
lldb::tid_t curr_tid = Host::GetCurrentThreadID();
if (pid == LLDB_INVALID_PROCESS_ID)
@@ -761,14 +711,12 @@ Host::SetThreadName (lldb::pid_t pid, ll
if (tid == LLDB_INVALID_THREAD_ID)
tid = curr_tid;
-#if defined(__APPLE__) && MAC_OS_X_VERSION_MAX_ALLOWED > MAC_OS_X_VERSION_10_5
// Set the pthread name if possible
if (pid == curr_pid && tid == curr_tid)
{
::pthread_setname_np (name);
}
#endif
- ThreadNameAccessor (false, pid, tid, name);
}
FileSpec
@@ -1519,6 +1467,52 @@ Host::RunShellCommand (const char *comma
}
+uint32_t
+Host::GetNumberCPUS ()
+{
+ static uint32_t g_num_cores = UINT32_MAX;
+ if (g_num_cores == UINT32_MAX)
+ {
+#if defined(__APPLE__) or defined (__linux__)
+
+ g_num_cores = ::sysconf(_SC_NPROCESSORS_ONLN);
+
+#elif defined(_WIN32) || defined(__WIN32__) || defined(__CYGWIN__)
+
+ // Header file for this might need to be included at the top of this file
+ SYSTEM_INFO system_info;
+ ::GetSystemInfo (&system_info);
+ g_num_cores = system_info.dwNumberOfProcessors;
+
+#else
+
+ // Assume POSIX support if a host specific case has not been supplied above
+ g_num_cores = 0;
+ int num_cores = 0;
+ size_t num_cores_len = sizeof(num_cores);
+ int mib[] = { CTL_HW, HW_AVAILCPU };
+
+ /* get the number of CPUs from the system */
+ if (sysctl(mib, sizeof(mib)/sizeof(int), &num_cores, &num_cores_len, NULL, 0) == 0 && (num_cores > 0))
+ {
+ g_num_cores = num_cores;
+ }
+ else
+ {
+ mib[1] = HW_NCPU;
+ num_cores_len = sizeof(num_cores);
+ if (sysctl(mib, sizeof(mib)/sizeof(int), &num_cores, &num_cores_len, NULL, 0) == 0 && (num_cores > 0))
+ {
+ if (num_cores > 0)
+ g_num_cores = num_cores;
+ }
+ }
+#endif
+ }
+ return g_num_cores;
+}
+
+
#if !defined (__APPLE__)
bool
Modified: lldb/branches/windows/source/Host/linux/Host.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/windows/source/Host/linux/Host.cpp?rev=179679&r1=179678&r2=179679&view=diff
==============================================================================
--- lldb/branches/windows/source/Host/linux/Host.cpp (original)
+++ lldb/branches/windows/source/Host/linux/Host.cpp Wed Apr 17 03:38:48 2013
@@ -9,7 +9,11 @@
// C Includes
#include <stdio.h>
+#ifndef _WIN32
#include <sys/utsname.h>
+#else
+#include <io.h>
+#endif
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
@@ -33,7 +37,15 @@ Host::GetOSVersion(uint32_t &major,
uint32_t &minor,
uint32_t &update)
{
- struct utsname un;
+#ifdef _WIN32
+ OSVERSIONINFO info;
+ GetVersionEx(&info);
+ major = info.dwMajorVersion;
+ minor = info.dwMinorVersion;
+ update = info.dwBuildNumber;
+ return true;
+#else
+ struct utsname un;
int status;
if (uname(&un))
@@ -41,6 +53,7 @@ Host::GetOSVersion(uint32_t &major,
status = sscanf(un.release, "%u.%u.%u", &major, &minor, &update);
return status == 3;
+#endif
}
Error
Modified: lldb/branches/windows/source/Host/macosx/Host.mm
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/windows/source/Host/macosx/Host.mm?rev=179679&r1=179678&r2=179679&view=diff
==============================================================================
--- lldb/branches/windows/source/Host/macosx/Host.mm (original)
+++ lldb/branches/windows/source/Host/macosx/Host.mm Wed Apr 17 03:38:48 2013
@@ -681,7 +681,7 @@ Host::OpenFileInExternalEditor (const Fi
uint32_t reserved2; // must be zero
} BabelAESelInfo;
- LogSP log(lldb_private::GetLogIfAnyCategoriesSet (LIBLLDB_LOG_HOST));
+ Log *log(lldb_private::GetLogIfAnyCategoriesSet (LIBLLDB_LOG_HOST));
char file_path[PATH_MAX];
file_spec.GetPath(file_path, PATH_MAX);
CFCString file_cfstr (file_path, kCFStringEncodingUTF8);
@@ -1079,7 +1079,7 @@ GetMacOSXProcessArgs (const ProcessInsta
if (::sysctl (proc_args_mib, 3, arg_data, &arg_data_size , NULL, 0) == 0)
{
DataExtractor data (arg_data, arg_data_size, lldb::endian::InlHostByteOrder(), sizeof(void *));
- uint32_t offset = 0;
+ lldb::offset_t offset = 0;
uint32_t argc = data.GetU32 (&offset);
const char *cstr;
@@ -1301,7 +1301,7 @@ static Error
getXPCAuthorization (ProcessLaunchInfo &launch_info)
{
Error error;
- LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_HOST | LIBLLDB_LOG_PROCESS));
+ Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_HOST | LIBLLDB_LOG_PROCESS));
if ((launch_info.GetUserID() == 0) && !authorizationRef)
{
@@ -1312,7 +1312,7 @@ getXPCAuthorization (ProcessLaunchInfo &
error.SetErrorString("Can't create authorizationRef.");
if (log)
{
- error.PutToLog(log.get(), "%s", error.AsCString());
+ error.PutToLog(log, "%s", error.AsCString());
}
return error;
}
@@ -1353,7 +1353,7 @@ getXPCAuthorization (ProcessLaunchInfo &
error.SetErrorStringWithFormat("Launching as root needs root authorization.");
if (log)
{
- error.PutToLog(log.get(), "%s", error.AsCString());
+ error.PutToLog(log, "%s", error.AsCString());
}
if (authorizationRef)
@@ -1376,7 +1376,7 @@ LaunchProcessXPC (const char *exe_path,
if (error.Fail())
return error;
- LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_HOST | LIBLLDB_LOG_PROCESS));
+ Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_HOST | LIBLLDB_LOG_PROCESS));
uid_t requested_uid = launch_info.GetUserID();
const char *xpc_service = nil;
@@ -1398,7 +1398,7 @@ LaunchProcessXPC (const char *exe_path,
error.SetErrorStringWithFormat("Launching root via XPC needs to externalize authorization reference.");
if (log)
{
- error.PutToLog(log.get(), "%s", error.AsCString());
+ error.PutToLog(log, "%s", error.AsCString());
}
return error;
}
@@ -1410,7 +1410,7 @@ LaunchProcessXPC (const char *exe_path,
error.SetErrorStringWithFormat("Launching via XPC is only currently available for either the login user or root.");
if (log)
{
- error.PutToLog(log.get(), "%s", error.AsCString());
+ error.PutToLog(log, "%s", error.AsCString());
}
return error;
}
@@ -1470,7 +1470,7 @@ LaunchProcessXPC (const char *exe_path,
error.SetErrorStringWithFormat("Problems with launching via XPC. Error type : %i, code : %i", errorType, errorCode);
if (log)
{
- error.PutToLog(log.get(), "%s", error.AsCString());
+ error.PutToLog(log, "%s", error.AsCString());
}
if (authorizationRef)
@@ -1486,7 +1486,7 @@ LaunchProcessXPC (const char *exe_path,
error.SetErrorStringWithFormat("Problems with launching via XPC. XPC error : %s", xpc_dictionary_get_string(reply, XPC_ERROR_KEY_DESCRIPTION));
if (log)
{
- error.PutToLog(log.get(), "%s", error.AsCString());
+ error.PutToLog(log, "%s", error.AsCString());
}
}
@@ -1501,13 +1501,13 @@ static Error
LaunchProcessPosixSpawn (const char *exe_path, ProcessLaunchInfo &launch_info, ::pid_t &pid)
{
Error error;
- LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_HOST | LIBLLDB_LOG_PROCESS));
+ Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_HOST | LIBLLDB_LOG_PROCESS));
posix_spawnattr_t attr;
error.SetError( ::posix_spawnattr_init (&attr), eErrorTypePOSIX);
if (error.Fail() || log)
- error.PutToLog(log.get(), "::posix_spawnattr_init ( &attr )");
+ error.PutToLog(log, "::posix_spawnattr_init ( &attr )");
if (error.Fail())
return error;
@@ -1525,7 +1525,7 @@ LaunchProcessPosixSpawn (const char *exe
short flags = GetPosixspawnFlags(launch_info);
error.SetError( ::posix_spawnattr_setflags (&attr, flags), eErrorTypePOSIX);
if (error.Fail() || log)
- error.PutToLog(log.get(), "::posix_spawnattr_setflags ( &attr, flags=0x%8.8x )", flags);
+ error.PutToLog(log, "::posix_spawnattr_setflags ( &attr, flags=0x%8.8x )", flags);
if (error.Fail())
return error;
@@ -1543,7 +1543,7 @@ LaunchProcessPosixSpawn (const char *exe
size_t ocount = 0;
error.SetError( ::posix_spawnattr_setbinpref_np (&attr, 1, &cpu, &ocount), eErrorTypePOSIX);
if (error.Fail() || log)
- error.PutToLog(log.get(), "::posix_spawnattr_setbinpref_np ( &attr, 1, cpu_type = 0x%8.8x, count => %llu )", cpu, (uint64_t)ocount);
+ error.PutToLog(log, "::posix_spawnattr_setbinpref_np ( &attr, 1, cpu_type = 0x%8.8x, count => %llu )", cpu, (uint64_t)ocount);
if (error.Fail() || ocount != 1)
return error;
@@ -1586,7 +1586,7 @@ LaunchProcessPosixSpawn (const char *exe
posix_spawn_file_actions_t file_actions;
error.SetError( ::posix_spawn_file_actions_init (&file_actions), eErrorTypePOSIX);
if (error.Fail() || log)
- error.PutToLog(log.get(), "::posix_spawn_file_actions_init ( &file_actions )");
+ error.PutToLog(log, "::posix_spawn_file_actions_init ( &file_actions )");
if (error.Fail())
return error;
@@ -1601,7 +1601,7 @@ LaunchProcessPosixSpawn (const char *exe
{
if (!ProcessLaunchInfo::FileAction::AddPosixSpawnFileAction (&file_actions,
launch_file_action,
- log.get(),
+ log,
error))
return error;
}
@@ -1617,7 +1617,7 @@ LaunchProcessPosixSpawn (const char *exe
if (error.Fail() || log)
{
- error.PutToLog(log.get(), "::posix_spawnp ( pid => %i, path = '%s', file_actions = %p, attr = %p, argv = %p, envp = %p )",
+ error.PutToLog(log, "::posix_spawnp ( pid => %i, path = '%s', file_actions = %p, attr = %p, argv = %p, envp = %p )",
pid,
exe_path,
&file_actions,
@@ -1644,7 +1644,7 @@ LaunchProcessPosixSpawn (const char *exe
if (error.Fail() || log)
{
- error.PutToLog(log.get(), "::posix_spawnp ( pid => %i, path = '%s', file_actions = NULL, attr = %p, argv = %p, envp = %p )",
+ error.PutToLog(log, "::posix_spawnp ( pid => %i, path = '%s', file_actions = NULL, attr = %p, argv = %p, envp = %p )",
pid,
exe_path,
&attr,
@@ -1790,7 +1790,7 @@ Host::StartMonitoringChildProcess (Host:
if (monitor_signals)
mask |= DISPATCH_PROC_SIGNAL;
- LogSP log(lldb_private::GetLogIfAnyCategoriesSet (LIBLLDB_LOG_HOST | LIBLLDB_LOG_PROCESS));
+ Log *log(lldb_private::GetLogIfAnyCategoriesSet (LIBLLDB_LOG_HOST | LIBLLDB_LOG_PROCESS));
dispatch_source_t source = ::dispatch_source_create (DISPATCH_SOURCE_TYPE_PROC,
Modified: lldb/branches/windows/source/Host/macosx/Symbols.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/windows/source/Host/macosx/Symbols.cpp?rev=179679&r1=179678&r2=179679&view=diff
==============================================================================
--- lldb/branches/windows/source/Host/macosx/Symbols.cpp (original)
+++ lldb/branches/windows/source/Host/macosx/Symbols.cpp Wed Apr 17 03:38:48 2013
@@ -58,7 +58,7 @@ SkinnyMachOFileContainsArchAndUUID
const lldb_private::UUID *uuid, // the UUID we are looking for
off_t file_offset,
DataExtractor& data,
- uint32_t data_offset,
+ lldb::offset_t data_offset,
const uint32_t magic
)
{
@@ -116,7 +116,7 @@ SkinnyMachOFileContainsArchAndUUID
for (i=0; i<ncmds; i++)
{
- const uint32_t cmd_offset = data_offset; // Save this data_offset in case parsing of the segment goes awry!
+ const lldb::offset_t cmd_offset = data_offset; // Save this data_offset in case parsing of the segment goes awry!
uint32_t cmd = data.GetU32(&data_offset);
uint32_t cmd_size = data.GetU32(&data_offset);
if (cmd == LoadCommandUUID)
@@ -124,18 +124,6 @@ SkinnyMachOFileContainsArchAndUUID
lldb_private::UUID file_uuid (data.GetData(&data_offset, 16), 16);
if (file_uuid == *uuid)
return true;
-
- // Emit some warning messages since the UUIDs do not match!
- char path_buf[PATH_MAX];
- path_buf[0] = '\0';
- const char *path = file_spec.GetPath(path_buf, PATH_MAX) ? path_buf
- : file_spec.GetFilename().AsCString();
- StreamString ss_m_uuid, ss_o_uuid;
- uuid->Dump(&ss_m_uuid);
- file_uuid.Dump(&ss_o_uuid);
- Host::SystemLog (Host::eSystemLogWarning,
- "warning: UUID mismatch detected between binary (%s) and:\n\t'%s' (%s)\n",
- ss_m_uuid.GetData(), path, ss_o_uuid.GetData());
return false;
}
data_offset = cmd_offset + cmd_size;
@@ -151,7 +139,7 @@ UniversalMachOFileContainsArchAndUUID
const lldb_private::UUID *uuid,
off_t file_offset,
DataExtractor& data,
- uint32_t data_offset,
+ lldb::offset_t data_offset,
const uint32_t magic
)
{
@@ -189,7 +177,7 @@ UniversalMachOFileContainsArchAndUUID
DataExtractor arch_data;
DataBufferSP data_buffer_sp (file_spec.ReadFileContents (file_offset + arch_offset, 0x1000));
arch_data.SetData(data_buffer_sp);
- uint32_t arch_data_offset = 0;
+ lldb::offset_t arch_data_offset = 0;
uint32_t arch_magic = arch_data.GetU32(&arch_data_offset);
switch (arch_magic)
@@ -222,7 +210,7 @@ FileAtPathContainsArchAndUUID
{
data.SetData(data_buffer_sp);
- uint32_t data_offset = 0;
+ lldb::offset_t data_offset = 0;
uint32_t magic = data.GetU32(&data_offset);
switch (magic)
@@ -701,7 +689,7 @@ Symbols::DownloadObjectAndSymbolFile (Mo
g_dsym_for_uuid_exe_exists = dsym_for_uuid_exe_spec.Exists();
if (!g_dsym_for_uuid_exe_exists)
{
- int bufsize;
+ long bufsize;
if ((bufsize = sysconf(_SC_GETPW_R_SIZE_MAX)) != -1)
{
char buffer[bufsize];
@@ -770,7 +758,7 @@ Symbols::DownloadObjectAndSymbolFile (Mo
CFCReleaser<CFDictionaryRef> plist((CFDictionaryRef)::CFPropertyListCreateFromXMLData (NULL, data.get(), kCFPropertyListImmutable, NULL));
- if (CFGetTypeID (plist.get()) == CFDictionaryGetTypeID ())
+ if (plist.get() && CFGetTypeID (plist.get()) == CFDictionaryGetTypeID ())
{
if (uuid_cstr)
{
Modified: lldb/branches/windows/source/Host/macosx/cfcpp/CFCMutableDictionary.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/windows/source/Host/macosx/cfcpp/CFCMutableDictionary.cpp?rev=179679&r1=179678&r2=179679&view=diff
==============================================================================
--- lldb/branches/windows/source/Host/macosx/cfcpp/CFCMutableDictionary.cpp (original)
+++ lldb/branches/windows/source/Host/macosx/cfcpp/CFCMutableDictionary.cpp Wed Apr 17 03:38:48 2013
@@ -432,6 +432,44 @@ CFCMutableDictionary::SetValueUInt64(CFS
}
bool
+CFCMutableDictionary::AddValueDouble(CFStringRef key, double value, bool can_create)
+{
+ CFMutableDictionaryRef dict = Dictionary(can_create);
+ if (dict != NULL)
+ {
+ // The number may appear negative if the MSBit is set in "value". Due to a limitation of
+ // CFNumber, there isn't a way to have it show up otherwise as of this writing.
+ CFCReleaser<CFNumberRef> cf_number(::CFNumberCreate (kCFAllocatorDefault, kCFNumberDoubleType, &value));
+ if (cf_number.get())
+ {
+ // Let the dictionary own the CFNumber
+ ::CFDictionaryAddValue (dict, key, cf_number.get());
+ return true;
+ }
+ }
+ return false;
+}
+
+bool
+CFCMutableDictionary::SetValueDouble(CFStringRef key, double value, bool can_create)
+{
+ CFMutableDictionaryRef dict = Dictionary(can_create);
+ if (dict != NULL)
+ {
+ // The number may appear negative if the MSBit is set in "value". Due to a limitation of
+ // CFNumber, there isn't a way to have it show up otherwise as of this writing.
+ CFCReleaser<CFNumberRef> cf_number(::CFNumberCreate (kCFAllocatorDefault, kCFNumberDoubleType, &value));
+ if (cf_number.get())
+ {
+ // Let the dictionary own the CFNumber
+ ::CFDictionarySetValue (dict, key, cf_number.get());
+ return true;
+ }
+ }
+ return false;
+}
+
+bool
CFCMutableDictionary::AddValueCString(CFStringRef key, const char *cstr, bool can_create)
{
CFMutableDictionaryRef dict = Dictionary(can_create);
Modified: lldb/branches/windows/source/Host/macosx/cfcpp/CFCMutableDictionary.h
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/windows/source/Host/macosx/cfcpp/CFCMutableDictionary.h?rev=179679&r1=179678&r2=179679&view=diff
==============================================================================
--- lldb/branches/windows/source/Host/macosx/cfcpp/CFCMutableDictionary.h (original)
+++ lldb/branches/windows/source/Host/macosx/cfcpp/CFCMutableDictionary.h Wed Apr 17 03:38:48 2013
@@ -53,6 +53,8 @@ public:
bool SetValueUInt32(CFStringRef key, uint32_t value, bool can_create = false);
bool AddValueUInt64(CFStringRef key, uint64_t value, bool can_create = false);
bool SetValueUInt64(CFStringRef key, uint64_t value, bool can_create = false);
+ bool AddValueDouble(CFStringRef key, double value, bool can_create = false);
+ bool SetValueDouble(CFStringRef key, double value, bool can_create = false);
bool AddValueCString(CFStringRef key, const char *cstr, bool can_create = false);
bool SetValueCString(CFStringRef key, const char *cstr, bool can_create = false);
void RemoveValue(const void *value);
Modified: lldb/branches/windows/source/Host/macosx/launcherXPCService/LauncherRootXPCService-Info.plist
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/windows/source/Host/macosx/launcherXPCService/LauncherRootXPCService-Info.plist?rev=179679&r1=179678&r2=179679&view=diff
==============================================================================
--- lldb/branches/windows/source/Host/macosx/launcherXPCService/LauncherRootXPCService-Info.plist (original)
+++ lldb/branches/windows/source/Host/macosx/launcherXPCService/LauncherRootXPCService-Info.plist Wed Apr 17 03:38:48 2013
@@ -25,7 +25,7 @@
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleVersion</key>
- <string>168</string>
+ <string>300.99.0</string>
<key>NSHumanReadableCopyright</key>
<string>Copyright © 2012 Apple Inc. All rights reserved.</string>
<key>XPCService</key>
Modified: lldb/branches/windows/source/Host/macosx/launcherXPCService/LauncherXPCService-Info.plist
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/windows/source/Host/macosx/launcherXPCService/LauncherXPCService-Info.plist?rev=179679&r1=179678&r2=179679&view=diff
==============================================================================
--- lldb/branches/windows/source/Host/macosx/launcherXPCService/LauncherXPCService-Info.plist (original)
+++ lldb/branches/windows/source/Host/macosx/launcherXPCService/LauncherXPCService-Info.plist Wed Apr 17 03:38:48 2013
@@ -25,7 +25,7 @@
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleVersion</key>
- <string>168</string>
+ <string>300.99.0</string>
<key>NSHumanReadableCopyright</key>
<string>Copyright © 2012 Apple Inc. All rights reserved.</string>
<key>XPCService</key>
Modified: lldb/branches/windows/source/Host/macosx/launcherXPCService/main.mm
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/windows/source/Host/macosx/launcherXPCService/main.mm?rev=179679&r1=179678&r2=179679&view=diff
==============================================================================
--- lldb/branches/windows/source/Host/macosx/launcherXPCService/main.mm (original)
+++ lldb/branches/windows/source/Host/macosx/launcherXPCService/main.mm Wed Apr 17 03:38:48 2013
@@ -16,6 +16,7 @@
#include <spawn.h>
#include <signal.h>
#include <assert.h>
+#include <sys/errno.h>
#include "LauncherXPCService.h"
// Declaration. Returns 0 if successful.
@@ -109,6 +110,31 @@ int get_args(xpc_object_t message, const
return 0;
}
+void _wait_for_child_exit(pid_t childPID)
+{
+ dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
+ dispatch_source_t source = dispatch_source_create(DISPATCH_SOURCE_TYPE_PROC, childPID, DISPATCH_PROC_EXIT, queue);
+
+ if (source) {
+ dispatch_source_set_cancel_handler(source, ^{
+ dispatch_release(source);
+ });
+
+ dispatch_source_set_event_handler(source, ^{
+
+ // Either finding the process was successful, or the process disappeared before libdispatch got around to hooking up the source.
+ dispatch_source_cancel(source);
+
+ int status, ret;
+ do {
+ ret = waitpid(childPID, &status, 0);
+ } while (ret < 0 && errno == EINTR);
+
+ });
+ dispatch_resume(source);
+ }
+}
+
static void launcherXPC_peer_event_handler(xpc_connection_t peer, xpc_object_t event)
{
xpc_type_t type = xpc_get_type(event);
@@ -154,6 +180,10 @@ static void launcherXPC_peer_event_handl
if (argvp) free(argvp);
if (envp) free(envp);
+
+ if (errorCode == 0) {
+ _wait_for_child_exit(childPID);
+ }
}
}
}
Modified: lldb/branches/windows/source/Interpreter/Args.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/windows/source/Interpreter/Args.cpp?rev=179679&r1=179678&r2=179679&view=diff
==============================================================================
--- lldb/branches/windows/source/Interpreter/Args.cpp (original)
+++ lldb/branches/windows/source/Interpreter/Args.cpp Wed Apr 17 03:38:48 2013
@@ -18,10 +18,10 @@
// Other libraries and framework includes
// Project includes
#include "lldb/Interpreter/Args.h"
-#include "lldb/Core/FormatManager.h"
#include "lldb/Core/Stream.h"
#include "lldb/Core/StreamFile.h"
#include "lldb/Core/StreamString.h"
+#include "lldb/DataFormatters/FormatManager.h"
#include "lldb/Interpreter/Options.h"
#include "lldb/Interpreter/CommandReturnObject.h"
#include "lldb/Target/Process.h"
@@ -100,15 +100,15 @@ Args::~Args ()
void
Args::Dump (Stream *s)
{
- const int argc = m_argv.size();
- for (int i=0; i<argc; ++i)
+ const size_t argc = m_argv.size();
+ for (size_t i=0; i<argc; ++i)
{
s->Indent();
const char *arg_cstr = m_argv[i];
if (arg_cstr)
- s->Printf("argv[%i]=\"%s\"\n", i, arg_cstr);
+ s->Printf("argv[%zi]=\"%s\"\n", i, arg_cstr);
else
- s->Printf("argv[%i]=NULL\n", i);
+ s->Printf("argv[%zi]=NULL\n", i);
}
s->EOL();
}
@@ -117,8 +117,8 @@ bool
Args::GetCommandString (std::string &command) const
{
command.clear();
- int argc = GetArgumentCount();
- for (int i=0; i<argc; ++i)
+ const size_t argc = GetArgumentCount();
+ for (size_t i=0; i<argc; ++i)
{
if (i > 0)
command += ' ';
@@ -131,7 +131,7 @@ bool
Args::GetQuotedCommandString (std::string &command) const
{
command.clear ();
- size_t argc = GetArgumentCount ();
+ const size_t argc = GetArgumentCount();
for (size_t i = 0; i < argc; ++i)
{
if (i > 0)
@@ -573,7 +573,7 @@ Args::DeleteArgumentAtIndex (size_t idx)
}
void
-Args::SetArguments (int argc, const char **argv)
+Args::SetArguments (size_t argc, const char **argv)
{
// m_argv will be rebuilt in UpdateArgvFromArgs() below, so there is
// no need to clear it here.
@@ -657,7 +657,7 @@ Args::ParseOptions (Options &options)
while (1)
{
int long_options_index = -1;
- val = ::getopt_long(GetArgumentCount(),
+ val = ::getopt_long_only(GetArgumentCount(),
GetArgumentVector(),
sstr.GetData(),
long_options,
@@ -725,11 +725,12 @@ Args::StringToSInt32 (const char *s, int
if (s && s[0])
{
char *end = NULL;
- int32_t uval = ::strtol (s, &end, base);
+ const long sval = ::strtol (s, &end, base);
if (*end == '\0')
{
- if (success_ptr) *success_ptr = true;
- return uval; // All characters were used, return the result
+ if (success_ptr)
+ *success_ptr = ((sval <= INT32_MAX) && (sval >= INT32_MIN));
+ return (int32_t)sval; // All characters were used, return the result
}
}
if (success_ptr) *success_ptr = false;
@@ -742,11 +743,12 @@ Args::StringToUInt32 (const char *s, uin
if (s && s[0])
{
char *end = NULL;
- uint32_t uval = ::strtoul (s, &end, base);
+ const unsigned long uval = ::strtoul (s, &end, base);
if (*end == '\0')
{
- if (success_ptr) *success_ptr = true;
- return uval; // All characters were used, return the result
+ if (success_ptr)
+ *success_ptr = (uval <= UINT32_MAX);
+ return (uint32_t)uval; // All characters were used, return the result
}
}
if (success_ptr) *success_ptr = false;
@@ -854,20 +856,21 @@ Args::StringToAddress (const ExecutionCo
// Since the compiler can't handle things like "main + 12" we should
// try to do this for now. The compliler doesn't like adding offsets
// to function pointer types.
- RegularExpression symbol_plus_offset_regex("^(.*)([-\\+])[[:space:]]*(0x[0-9A-Fa-f]+|[0-9]+)[[:space:]]*$");
- if (symbol_plus_offset_regex.Execute(s, 3))
+ static RegularExpression g_symbol_plus_offset_regex("^(.*)([-\\+])[[:space:]]*(0x[0-9A-Fa-f]+|[0-9]+)[[:space:]]*$");
+ RegularExpression::Match regex_match(3);
+ if (g_symbol_plus_offset_regex.Execute(s, ®ex_match))
{
uint64_t offset = 0;
bool add = true;
std::string name;
std::string str;
- if (symbol_plus_offset_regex.GetMatchAtIndex(s, 1, name))
+ if (regex_match.GetMatchAtIndex(s, 1, name))
{
- if (symbol_plus_offset_regex.GetMatchAtIndex(s, 2, str))
+ if (regex_match.GetMatchAtIndex(s, 2, str))
{
add = str[0] == '+';
- if (symbol_plus_offset_regex.GetMatchAtIndex(s, 3, str))
+ if (regex_match.GetMatchAtIndex(s, 3, str))
{
offset = Args::StringToUInt64(str.c_str(), 0, 0, &success);
@@ -905,6 +908,33 @@ Args::StringToAddress (const ExecutionCo
return fail_value;
}
+const char *
+Args::StripSpaces (std::string &s, bool leading, bool trailing, bool return_null_if_empty)
+{
+ static const char *k_white_space = " \t\v";
+ if (!s.empty())
+ {
+ if (leading)
+ {
+ size_t pos = s.find_first_not_of (k_white_space);
+ if (pos == std::string::npos)
+ s.clear();
+ else if (pos > 0)
+ s.erase(0, pos);
+ }
+
+ if (trailing)
+ {
+ size_t rpos = s.find_last_not_of(k_white_space);
+ if (rpos != std::string::npos && rpos + 1 < s.size())
+ s.erase(rpos + 1);
+ }
+ }
+ if (return_null_if_empty && s.empty())
+ return NULL;
+ return s.c_str();
+}
+
bool
Args::StringToBoolean (const char *s, bool fail_value, bool *success_ptr)
{
@@ -943,8 +973,7 @@ Args::StringToVersion (const char *s, ui
if (s && s[0])
{
char *pos = NULL;
- uint32_t uval32;
- uval32 = ::strtoul (s, &pos, 0);
+ unsigned long uval32 = ::strtoul (s, &pos, 0);
if (pos == s)
return s;
major = uval32;
@@ -994,7 +1023,7 @@ Args::GetShellSafeArgument (const char *
}
-int32_t
+int64_t
Args::StringToOptionEnum (const char *s, OptionEnumValueElement *enum_values, int32_t fail_value, Error &error)
{
if (enum_values)
@@ -1054,7 +1083,7 @@ Args::StringToFormat
(
const char *s,
lldb::Format &format,
- uint32_t *byte_size_ptr
+ size_t *byte_size_ptr
)
{
format = eFormatInvalid;
@@ -1287,7 +1316,10 @@ Args::ParseAliasOptions (Options &option
while (1)
{
int long_options_index = -1;
- val = ::getopt_long (GetArgumentCount(), GetArgumentVector(), sstr.GetData(), long_options,
+ val = ::getopt_long_only (GetArgumentCount(),
+ GetArgumentVector(),
+ sstr.GetData(),
+ long_options,
&long_options_index);
if (val == -1)
@@ -1465,8 +1497,8 @@ Args::ParseArgsForCompletion
int val;
const OptionDefinition *opt_defs = options.GetDefinitions();
- // Fooey... getopt_long permutes the GetArgumentVector to move the options to the front.
- // So we have to build another Arg and pass that to getopt_long so it doesn't
+ // Fooey... getopt_long_only permutes the GetArgumentVector to move the options to the front.
+ // So we have to build another Arg and pass that to getopt_long_only so it doesn't
// change the one we have.
std::vector<const char *> dummy_vec (GetArgumentVector(), GetArgumentVector() + GetArgumentCount() + 1);
@@ -1480,9 +1512,9 @@ Args::ParseArgsForCompletion
int parse_start = optind;
int long_options_index = -1;
- val = ::getopt_long (dummy_vec.size() - 1,
- (char *const *) &dummy_vec.front(),
- sstr.GetData(),
+ val = ::getopt_long_only (dummy_vec.size() - 1,
+ (char *const *) &dummy_vec.front(),
+ sstr.GetData(),
long_options,
&long_options_index);
@@ -1498,7 +1530,7 @@ Args::ParseArgsForCompletion
// Handling the "--" is a little tricky, since that may mean end of options or arguments, or the
// user might want to complete options by long name. I make this work by checking whether the
// cursor is in the "--" argument, and if so I assume we're completing the long option, otherwise
- // I let it pass to getopt_long which will terminate the option parsing.
+ // I let it pass to getopt_long_only which will terminate the option parsing.
// Note, in either case we continue parsing the line so we can figure out what other options
// were passed. This will be useful when we come to restricting completions based on what other
// options we've seen on the line.
@@ -1614,7 +1646,7 @@ Args::ParseArgsForCompletion
}
// Finally we have to handle the case where the cursor index points at a single "-". We want to mark that in
- // the option_element_vector, but only if it is not after the "--". But it turns out that getopt_long just ignores
+ // the option_element_vector, but only if it is not after the "--". But it turns out that getopt_long_only just ignores
// an isolated "-". So we have to look it up by hand here. We only care if it is AT the cursor position.
if ((dash_dash_pos == -1 || cursor_index < dash_dash_pos)
@@ -1676,8 +1708,7 @@ Args::EncodeEscapeSequences (const char
unsigned long octal_value = ::strtoul (oct_str, NULL, 8);
if (octal_value <= UINT8_MAX)
{
- const char octal_char = octal_value;
- dst.append(1, octal_char);
+ dst.append(1, (char)octal_value);
}
}
break;
Modified: lldb/branches/windows/source/Interpreter/CommandInterpreter.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/windows/source/Interpreter/CommandInterpreter.cpp?rev=179679&r1=179678&r2=179679&view=diff
==============================================================================
--- lldb/branches/windows/source/Interpreter/CommandInterpreter.cpp (original)
+++ lldb/branches/windows/source/Interpreter/CommandInterpreter.cpp Wed Apr 17 03:38:48 2013
@@ -44,6 +44,7 @@
#include "../Commands/CommandObjectVersion.h"
#include "../Commands/CommandObjectWatchpoint.h"
+
#include "lldb/Core/Debugger.h"
#include "lldb/Core/InputReader.h"
#include "lldb/Core/Log.h"
@@ -53,8 +54,9 @@
#include "lldb/Host/Host.h"
#include "lldb/Interpreter/Args.h"
-#include "lldb/Interpreter/CommandReturnObject.h"
+#include "lldb/Interpreter/CommandCompletions.h"
#include "lldb/Interpreter/CommandInterpreter.h"
+#include "lldb/Interpreter/CommandReturnObject.h"
#include "lldb/Interpreter/Options.h"
#include "lldb/Interpreter/ScriptInterpreterNone.h"
#include "lldb/Interpreter/ScriptInterpreterPython.h"
@@ -74,12 +76,14 @@ static PropertyDefinition
g_properties[] =
{
{ "expand-regex-aliases", OptionValue::eTypeBoolean, true, false, NULL, NULL, "If true, regular expression alias commands will show the expanded command that will be executed. This can be used to debug new regular expression alias commands." },
+ { "prompt-on-quit", OptionValue::eTypeBoolean, true, true, NULL, NULL, "If true, LLDB will prompt you before quitting if there are any live processes being debugged. If false, LLDB will quit without asking in any case." },
{ NULL , OptionValue::eTypeInvalid, true, 0 , NULL, NULL, NULL }
};
enum
{
- ePropertyExpandRegexAliases = 0
+ ePropertyExpandRegexAliases = 0,
+ ePropertyPromptOnQuit = 1
};
ConstString &
@@ -123,7 +127,12 @@ CommandInterpreter::GetExpandRegexAliase
return m_collection_sp->GetPropertyAtIndexAsBoolean (NULL, idx, g_properties[idx].default_uint_value != 0);
}
-
+bool
+CommandInterpreter::GetPromptOnQuit () const
+{
+ const uint32_t idx = ePropertyPromptOnQuit;
+ return m_collection_sp->GetPropertyAtIndexAsBoolean (NULL, idx, g_properties[idx].default_uint_value != 0);
+}
void
CommandInterpreter::Initialize ()
@@ -215,13 +224,19 @@ CommandInterpreter::Initialize ()
AddAlias ("t", cmd_obj_sp);
}
- cmd_obj_sp = GetCommandSPExact ("source list", false);
+ cmd_obj_sp = GetCommandSPExact ("_regexp-list", false);
if (cmd_obj_sp)
{
AddAlias ("l", cmd_obj_sp);
AddAlias ("list", cmd_obj_sp);
}
+ cmd_obj_sp = GetCommandSPExact ("_regexp-env", false);
+ if (cmd_obj_sp)
+ {
+ AddAlias ("env", cmd_obj_sp);
+ }
+
cmd_obj_sp = GetCommandSPExact ("memory read", false);
if (cmd_obj_sp)
AddAlias ("x", cmd_obj_sp);
@@ -344,34 +359,15 @@ CommandInterpreter::LoadCommandDictionar
{
Timer scoped_timer (__PRETTY_FUNCTION__, __PRETTY_FUNCTION__);
- // **** IMPORTANT **** IMPORTANT *** IMPORTANT *** **** IMPORTANT **** IMPORTANT *** IMPORTANT ***
- //
- // Command objects that are used as cross reference objects (i.e. they inherit from CommandObjectCrossref)
- // *MUST* be created and put into the command dictionary *BEFORE* any multi-word commands (which may use
- // the cross-referencing stuff) are created!!!
- //
- // **** IMPORTANT **** IMPORTANT *** IMPORTANT *** **** IMPORTANT **** IMPORTANT *** IMPORTANT ***
-
-
- // Command objects that inherit from CommandObjectCrossref must be created before other command objects
- // are created. This is so that when another command is created that needs to go into a crossref object,
- // the crossref object exists and is ready to take the cross reference. Put the cross referencing command
- // objects into the CommandDictionary now, so they are ready for use when the other commands get created.
-
- // Non-CommandObjectCrossref commands can now be created.
-
lldb::ScriptLanguage script_language = m_debugger.GetScriptLanguage();
m_command_dict["apropos"] = CommandObjectSP (new CommandObjectApropos (*this));
m_command_dict["breakpoint"]= CommandObjectSP (new CommandObjectMultiwordBreakpoint (*this));
- //m_command_dict["call"] = CommandObjectSP (new CommandObjectCall (*this));
m_command_dict["command"] = CommandObjectSP (new CommandObjectMultiwordCommands (*this));
m_command_dict["disassemble"] = CommandObjectSP (new CommandObjectDisassemble (*this));
m_command_dict["expression"]= CommandObjectSP (new CommandObjectExpression (*this));
-// m_command_dict["file"] = CommandObjectSP (new CommandObjectFile (*this));
m_command_dict["frame"] = CommandObjectSP (new CommandObjectMultiwordFrame (*this));
m_command_dict["help"] = CommandObjectSP (new CommandObjectHelp (*this));
- /// m_command_dict["image"] = CommandObjectSP (new CommandObjectImage (*this));
m_command_dict["log"] = CommandObjectSP (new CommandObjectLog (*this));
m_command_dict["memory"] = CommandObjectSP (new CommandObjectMemory (*this));
m_command_dict["platform"] = CommandObjectSP (new CommandObjectPlatform (*this));
@@ -390,10 +386,11 @@ CommandInterpreter::LoadCommandDictionar
const char *break_regexes[][2] = {{"^(.*[^[:space:]])[[:space:]]*:[[:space:]]*([[:digit:]]+)[[:space:]]*$", "breakpoint set --file '%1' --line %2"},
{"^([[:digit:]]+)[[:space:]]*$", "breakpoint set --line %1"},
- {"^(0x[[:xdigit:]]+)[[:space:]]*$", "breakpoint set --address %1"},
- {"^[\"']?([-+]\\[.*\\])[\"']?[[:space:]]*$", "breakpoint set --name '%1'"},
+ {"^\\*?(0x[[:xdigit:]]+)[[:space:]]*$", "breakpoint set --address %1"},
+ {"^[\"']?([-+]?\\[.*\\])[\"']?[[:space:]]*$", "breakpoint set --name '%1'"},
{"^(-.*)$", "breakpoint set %1"},
{"^(.*[^[:space:]])`(.*[^[:space:]])[[:space:]]*$", "breakpoint set --name '%2' --shlib '%1'"},
+ {"^\\&(.*[^[:space:]])[[:space:]]*$", "breakpoint set --name '%1' --skip-prologue=0"},
{"^(.*[^[:space:]])[[:space:]]*$", "breakpoint set --name '%1'"}};
size_t num_regexes = sizeof break_regexes/sizeof(char *[2]);
@@ -402,7 +399,10 @@ CommandInterpreter::LoadCommandDictionar
break_regex_cmd_ap(new CommandObjectRegexCommand (*this,
"_regexp-break",
"Set a breakpoint using a regular expression to specify the location, where <linenum> is in decimal and <address> is in hex.",
- "_regexp-break [<filename>:<linenum>]\n_regexp-break [<linenum>]\n_regexp-break [<address>]\n_regexp-break <...>", 2));
+ "_regexp-break [<filename>:<linenum>]\n_regexp-break [<linenum>]\n_regexp-break [<address>]\n_regexp-break <...>",
+ 2,
+ CommandCompletions::eSymbolCompletion |
+ CommandCompletions::eSourceFileCompletion));
if (break_regex_cmd_ap.get())
{
@@ -426,7 +426,10 @@ CommandInterpreter::LoadCommandDictionar
tbreak_regex_cmd_ap(new CommandObjectRegexCommand (*this,
"_regexp-tbreak",
"Set a one shot breakpoint using a regular expression to specify the location, where <linenum> is in decimal and <address> is in hex.",
- "_regexp-tbreak [<filename>:<linenum>]\n_regexp-break [<linenum>]\n_regexp-break [<address>]\n_regexp-break <...>", 2));
+ "_regexp-tbreak [<filename>:<linenum>]\n_regexp-break [<linenum>]\n_regexp-break [<address>]\n_regexp-break <...>",
+ 2,
+ CommandCompletions::eSymbolCompletion |
+ CommandCompletions::eSourceFileCompletion));
if (tbreak_regex_cmd_ap.get())
{
@@ -454,7 +457,8 @@ CommandInterpreter::LoadCommandDictionar
attach_regex_cmd_ap(new CommandObjectRegexCommand (*this,
"_regexp-attach",
"Attach to a process id if in decimal, otherwise treat the argument as a process name to attach to.",
- "_regexp-attach [<pid>]\n_regexp-attach [<process-name>]", 2));
+ "_regexp-attach [<pid>]\n_regexp-attach [<process-name>]",
+ 2));
if (attach_regex_cmd_ap.get())
{
if (attach_regex_cmd_ap->AddRegexCommand("^([0-9]+)[[:space:]]*$", "process attach --pid %1") &&
@@ -575,6 +579,43 @@ CommandInterpreter::LoadCommandDictionar
}
}
+ std::auto_ptr<CommandObjectRegexCommand>
+ list_regex_cmd_ap(new CommandObjectRegexCommand (*this,
+ "_regexp-list",
+ "Implements the GDB 'list' command in all of its forms except FILE:FUNCTION and maps them to the appropriate 'source list' commands.",
+ "_regexp-list [<line>]\n_regexp-attach [<file>:<line>]\n_regexp-attach [<file>:<line>]",
+ 2,
+ CommandCompletions::eSourceFileCompletion));
+ if (list_regex_cmd_ap.get())
+ {
+ if (list_regex_cmd_ap->AddRegexCommand("^([0-9]+)[[:space:]]*$", "source list --line %1") &&
+ list_regex_cmd_ap->AddRegexCommand("^(.*[^[:space:]])[[:space:]]*:[[:space:]]*([[:digit:]]+)[[:space:]]*$", "source list --file '%1' --line %2") &&
+ list_regex_cmd_ap->AddRegexCommand("^\\*?(0x[[:xdigit:]]+)[[:space:]]*$", "source list --address %1") &&
+ list_regex_cmd_ap->AddRegexCommand("^-[[:space:]]*$", "source list --reverse") &&
+ list_regex_cmd_ap->AddRegexCommand("^-([[:digit:]]+)[[:space:]]*$", "source list --reverse --count %1") &&
+ list_regex_cmd_ap->AddRegexCommand("^(.+)$", "source list --name \"%1\"") &&
+ list_regex_cmd_ap->AddRegexCommand("^$", "source list"))
+ {
+ CommandObjectSP list_regex_cmd_sp(list_regex_cmd_ap.release());
+ m_command_dict[list_regex_cmd_sp->GetCommandName ()] = list_regex_cmd_sp;
+ }
+ }
+
+ std::auto_ptr<CommandObjectRegexCommand>
+ env_regex_cmd_ap(new CommandObjectRegexCommand (*this,
+ "_regexp-env",
+ "Implements a shortcut to viewing and setting environment variables.",
+ "_regexp-env\n_regexp-env FOO=BAR", 2));
+ if (env_regex_cmd_ap.get())
+ {
+ if (env_regex_cmd_ap->AddRegexCommand("^$", "settings show target.env-vars") &&
+ env_regex_cmd_ap->AddRegexCommand("^([A-Za-z_][A-Za-z_0-9]*=.*)$", "settings set target.env-vars %1"))
+ {
+ CommandObjectSP env_regex_cmd_sp(env_regex_cmd_ap.release());
+ m_command_dict[env_regex_cmd_sp->GetCommandName ()] = env_regex_cmd_sp;
+ }
+ }
+
}
int
@@ -595,7 +636,7 @@ CommandObjectSP
CommandInterpreter::GetCommandSP (const char *cmd_cstr, bool include_aliases, bool exact, StringList *matches)
{
CommandObject::CommandMap::iterator pos;
- CommandObjectSP ret_val;
+ CommandObjectSP command_sp;
std::string cmd(cmd_cstr);
@@ -603,24 +644,24 @@ CommandInterpreter::GetCommandSP (const
{
pos = m_command_dict.find(cmd);
if (pos != m_command_dict.end())
- ret_val = pos->second;
+ command_sp = pos->second;
}
if (include_aliases && HasAliases())
{
pos = m_alias_dict.find(cmd);
if (pos != m_alias_dict.end())
- ret_val = pos->second;
+ command_sp = pos->second;
}
if (HasUserCommands())
{
pos = m_user_dict.find(cmd);
if (pos != m_user_dict.end())
- ret_val = pos->second;
+ command_sp = pos->second;
}
- if (!exact && !ret_val)
+ if (!exact && !command_sp)
{
// We will only get into here if we didn't find any exact matches.
@@ -690,13 +731,13 @@ CommandInterpreter::GetCommandSP (const
return user_match_sp;
}
}
- else if (matches && ret_val)
+ else if (matches && command_sp)
{
matches->AppendString (cmd_cstr);
}
- return ret_val;
+ return command_sp;
}
bool
@@ -866,7 +907,7 @@ CommandInterpreter::ProcessAliasOptionsA
options_string)));
else
{
- int argc = args.GetArgumentCount();
+ const size_t argc = args.GetArgumentCount();
for (size_t i = 0; i < argc; ++i)
if (strcmp (args.GetArgumentAtIndex (i), "") != 0)
option_arg_vector->push_back
@@ -880,6 +921,40 @@ CommandInterpreter::ProcessAliasOptionsA
}
bool
+CommandInterpreter::GetAliasFullName (const char *cmd, std::string &full_name)
+{
+ bool exact_match = (m_alias_dict.find(cmd) != m_alias_dict.end());
+ if (exact_match)
+ {
+ full_name.assign(cmd);
+ return exact_match;
+ }
+ else
+ {
+ StringList matches;
+ size_t num_alias_matches;
+ num_alias_matches = CommandObject::AddNamesMatchingPartialString (m_alias_dict, cmd, matches);
+ if (num_alias_matches == 1)
+ {
+ // Make sure this isn't shadowing a command in the regular command space:
+ StringList regular_matches;
+ const bool include_aliases = false;
+ const bool exact = false;
+ CommandObjectSP cmd_obj_sp(GetCommandSP (cmd, include_aliases, exact, ®ular_matches));
+ if (cmd_obj_sp || regular_matches.GetSize() > 0)
+ return false;
+ else
+ {
+ full_name.assign (matches.GetStringAtIndex(0));
+ return true;
+ }
+ }
+ else
+ return false;
+ }
+}
+
+bool
CommandInterpreter::AliasExists (const char *cmd)
{
return m_alias_dict.find(cmd) != m_alias_dict.end();
@@ -976,7 +1051,7 @@ CommandInterpreter::GetHelp (CommandRetu
uint32_t cmd_types)
{
CommandObject::CommandMap::const_iterator pos;
- uint32_t max_len = FindLongestCommandWord (m_command_dict);
+ size_t max_len = FindLongestCommandWord (m_command_dict);
if ( (cmd_types & eCommandTypesBuiltin) == eCommandTypesBuiltin )
{
@@ -1322,6 +1397,7 @@ CommandInterpreter::PreprocessCommand (s
EvaluateExpressionOptions options;
options.SetCoerceToId(false)
.SetUnwindOnError(true)
+ .SetIgnoreBreakpoints(true)
.SetKeepInMemory(false)
.SetRunOthers(true)
.SetTimeoutUsec(0);
@@ -1377,6 +1453,9 @@ CommandInterpreter::PreprocessCommand (s
case eExecutionInterrupted:
error.SetErrorStringWithFormat("expression interrupted for the expression '%s'", expr_str.c_str());
break;
+ case eExecutionHitBreakpoint:
+ error.SetErrorStringWithFormat("expression hit breakpoint for the expression '%s'", expr_str.c_str());
+ break;
case eExecutionTimedOut:
error.SetErrorStringWithFormat("expression timed out for the expression '%s'", expr_str.c_str());
break;
@@ -1409,7 +1488,7 @@ CommandInterpreter::HandleCommand (const
std::string command_string (command_line);
std::string original_command_string (command_line);
- LogSP log (lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_COMMANDS));
+ Log *log (lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_COMMANDS));
Host::SetCrashDescriptionWithFormat ("HandleCommand(command = \"%s\")", command_line);
// Make a scoped cleanup object that will clear the crash description string
@@ -1527,10 +1606,11 @@ CommandInterpreter::HandleCommand (const
ExtractCommand (command_string, next_word, suffix, quote_char);
if (cmd_obj == NULL)
{
- if (AliasExists (next_word.c_str()))
+ std::string full_name;
+ if (GetAliasFullName(next_word.c_str(), full_name))
{
std::string alias_result;
- cmd_obj = BuildAliasResult (next_word.c_str(), command_string, alias_result, result);
+ cmd_obj = BuildAliasResult (full_name.c_str(), command_string, alias_result, result);
revised_command_line.Printf ("%s", alias_result.c_str());
if (cmd_obj)
{
@@ -1586,21 +1666,15 @@ CommandInterpreter::HandleCommand (const
if (cmd_obj == NULL)
{
- uint32_t num_matches = matches.GetSize();
+ const size_t num_matches = matches.GetSize();
if (matches.GetSize() > 1) {
- std::string error_msg;
- error_msg.assign ("Ambiguous command '");
- error_msg.append(next_word.c_str());
- error_msg.append ("'.");
-
- error_msg.append (" Possible matches:");
+ StreamString error_msg;
+ error_msg.Printf ("Ambiguous command '%s'. Possible matches:\n", next_word.c_str());
for (uint32_t i = 0; i < num_matches; ++i) {
- error_msg.append ("\n\t");
- error_msg.append (matches.GetStringAtIndex(i));
+ error_msg.Printf ("\t%s\n", matches.GetStringAtIndex(i));
}
- error_msg.append ("\n");
- result.AppendRawError (error_msg.c_str(), error_msg.size());
+ result.AppendRawError (error_msg.GetString().c_str());
} else {
// We didn't have only one match, otherwise we wouldn't get here.
assert(num_matches == 0);
@@ -1768,7 +1842,7 @@ CommandInterpreter::HandleCommand (const
error_msg.append (matches.GetStringAtIndex (i));
}
error_msg.append ("\n");
- result.AppendRawError (error_msg.c_str(), error_msg.size());
+ result.AppendRawError (error_msg.c_str());
}
else
result.AppendErrorWithFormat ("Unrecognized command '%s'.\n", command_args.GetArgumentAtIndex (0));
@@ -1948,7 +2022,7 @@ CommandInterpreter::HandleCompletion (co
std::string common_prefix;
matches.LongestCommonPrefix (common_prefix);
- int partial_name_len = command_partial_str.size();
+ const size_t partial_name_len = command_partial_str.size();
// If we matched a unique single command, add a space...
// Only do this if the completer told us this was a complete word, however...
@@ -2095,20 +2169,6 @@ CommandInterpreter::Confirm (const char
return response;
}
-
-void
-CommandInterpreter::CrossRegisterCommand (const char * dest_cmd, const char * object_type)
-{
- CommandObjectSP cmd_obj_sp = GetCommandSPExact (dest_cmd, true);
-
- if (cmd_obj_sp)
- {
- CommandObject *cmd_obj = cmd_obj_sp.get();
- if (cmd_obj->IsCrossRefObject ())
- cmd_obj->AddObject (object_type);
- }
-}
-
OptionArgVectorSP
CommandInterpreter::GetAliasOptions (const char *alias_name)
{
@@ -2202,7 +2262,7 @@ CommandInterpreter::BuildAliasCommandArg
}
OptionArgVector *option_arg_vector = option_arg_vector_sp.get();
- int old_size = cmd_args.GetArgumentCount();
+ const size_t old_size = cmd_args.GetArgumentCount();
std::vector<bool> used (old_size + 1, false);
used[0] = true;
@@ -2576,7 +2636,7 @@ CommandInterpreter::GetScriptInterpreter
static Mutex g_interpreter_mutex(Mutex::eMutexTypeRecursive);
Mutex::Locker interpreter_lock(g_interpreter_mutex);
- LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_OBJECT));
+ Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_OBJECT));
if (log)
log->Printf("Initializing the ScriptInterpreter now\n");
@@ -2617,7 +2677,7 @@ CommandInterpreter::OutputFormattedHelpT
const char *word_text,
const char *separator,
const char *help_text,
- uint32_t max_word_len)
+ size_t max_word_len)
{
const uint32_t max_columns = m_debugger.GetTerminalWidth();
@@ -2626,7 +2686,7 @@ CommandInterpreter::OutputFormattedHelpT
strm.IndentMore (indent_size);
StreamString text_strm;
- text_strm.Printf ("%-*s %s %s", max_word_len, word_text, separator, help_text);
+ text_strm.Printf ("%-*s %s %s", (int)max_word_len, word_text, separator, help_text);
size_t len = text_strm.GetSize();
const char *text = text_strm.GetData();
@@ -2646,10 +2706,9 @@ CommandInterpreter::OutputFormattedHelpT
// We need to break it up into multiple lines.
bool first_line = true;
int text_width;
- int start = 0;
- int end = start;
- int final_end = strlen (text);
- int sub_len;
+ size_t start = 0;
+ size_t end = start;
+ const size_t final_end = strlen (text);
while (end < final_end)
{
@@ -2677,7 +2736,7 @@ CommandInterpreter::OutputFormattedHelpT
assert (end > 0);
}
- sub_len = end - start;
+ const size_t sub_len = end - start;
if (start != 0)
strm.EOL();
if (!first_line)
@@ -2786,7 +2845,7 @@ CommandInterpreter::DumpHistory (Stream
void
CommandInterpreter::DumpHistory (Stream &stream, uint32_t start, uint32_t end) const
{
- const size_t last_idx = std::min<size_t>(m_command_history.size(), end + 1);
+ const size_t last_idx = std::min<size_t>(m_command_history.size(), end==UINT32_MAX ? UINT32_MAX : end + 1);
for (size_t i = start; i < last_idx; i++)
{
if (!m_command_history[i].empty())
@@ -2805,7 +2864,7 @@ CommandInterpreter::FindHistoryString (c
if (input_str[1] == '-')
{
bool success;
- uint32_t idx = Args::StringToUInt32 (input_str+2, 0, 0, &success);
+ size_t idx = Args::StringToUInt32 (input_str+2, 0, 0, &success);
if (!success)
return NULL;
if (idx > m_command_history.size())
Modified: lldb/branches/windows/source/Interpreter/CommandObject.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/windows/source/Interpreter/CommandObject.cpp?rev=179679&r1=179678&r2=179679&view=diff
==============================================================================
--- lldb/branches/windows/source/Interpreter/CommandObject.cpp (original)
+++ lldb/branches/windows/source/Interpreter/CommandObject.cpp Wed Apr 17 03:38:48 2013
@@ -171,7 +171,7 @@ CommandObject::ParseOptions
Error error;
options->NotifyOptionParsingStarting();
- // ParseOptions calls getopt_long, which always skips the zero'th item in the array and starts at position 1,
+ // ParseOptions calls getopt_long_only, which always skips the zero'th item in the array and starts at position 1,
// so we need to push a dummy value into position zero.
args.Unshift("dummy_string");
error = args.ParseOptions (*options);
@@ -210,8 +210,77 @@ CommandObject::ParseOptions
bool
-CommandObject::CheckFlags (CommandReturnObject &result)
+CommandObject::CheckRequirements (CommandReturnObject &result)
{
+#ifdef LLDB_CONFIGURATION_DEBUG
+ // Nothing should be stored in m_exe_ctx between running commands as m_exe_ctx
+ // has shared pointers to the target, process, thread and frame and we don't
+ // want any CommandObject instances to keep any of these objects around
+ // longer than for a single command. Every command should call
+ // CommandObject::Cleanup() after it has completed
+ assert (m_exe_ctx.GetTargetPtr() == NULL);
+ assert (m_exe_ctx.GetProcessPtr() == NULL);
+ assert (m_exe_ctx.GetThreadPtr() == NULL);
+ assert (m_exe_ctx.GetFramePtr() == NULL);
+#endif
+
+ // Lock down the interpreter's execution context prior to running the
+ // command so we guarantee the selected target, process, thread and frame
+ // can't go away during the execution
+ m_exe_ctx = m_interpreter.GetExecutionContext();
+
+ const uint32_t flags = GetFlags().Get();
+ if (flags & (eFlagRequiresTarget |
+ eFlagRequiresProcess |
+ eFlagRequiresThread |
+ eFlagRequiresFrame |
+ eFlagTryTargetAPILock ))
+ {
+
+ if ((flags & eFlagRequiresTarget) && !m_exe_ctx.HasTargetScope())
+ {
+ result.AppendError (GetInvalidTargetDescription());
+ return false;
+ }
+
+ if ((flags & eFlagRequiresProcess) && !m_exe_ctx.HasProcessScope())
+ {
+ result.AppendError (GetInvalidProcessDescription());
+ return false;
+ }
+
+ if ((flags & eFlagRequiresThread) && !m_exe_ctx.HasThreadScope())
+ {
+ result.AppendError (GetInvalidThreadDescription());
+ return false;
+ }
+
+ if ((flags & eFlagRequiresFrame) && !m_exe_ctx.HasFrameScope())
+ {
+ result.AppendError (GetInvalidFrameDescription());
+ return false;
+ }
+
+ if ((flags & eFlagRequiresRegContext) && (m_exe_ctx.GetRegisterContext() == NULL))
+ {
+ result.AppendError (GetInvalidRegContextDescription());
+ return false;
+ }
+
+ if (flags & eFlagTryTargetAPILock)
+ {
+ Target *target = m_exe_ctx.GetTargetPtr();
+ if (target)
+ {
+ if (m_api_locker.TryLock (target->GetAPIMutex(), NULL) == false)
+ {
+ result.AppendError ("failed to get API lock");
+ return false;
+ }
+ }
+ }
+ }
+
if (GetFlags().AnySet (CommandObject::eFlagProcessMustBeLaunched | CommandObject::eFlagProcessMustBePaused))
{
Process *process = m_interpreter.GetExecutionContext().GetProcessPtr();
@@ -265,6 +334,14 @@ CommandObject::CheckFlags (CommandReturn
return true;
}
+void
+CommandObject::Cleanup ()
+{
+ m_exe_ctx.Clear();
+ m_api_locker.Unlock();
+}
+
+
class CommandDictCommandPartialMatch
{
public:
@@ -276,13 +353,9 @@ class CommandDictCommandPartialMatch
{
// A NULL or empty string matches everything.
if (m_match_str == NULL || *m_match_str == '\0')
- return 1;
+ return true;
- size_t found = map_element.first.find (m_match_str, 0);
- if (found == std::string::npos)
- return 0;
- else
- return found == 0;
+ return map_element.first.find (m_match_str, 0) == 0;
}
private:
@@ -345,7 +418,7 @@ CommandObject::HandleCompletion
// I stick an element on the end of the input, because if the last element is
- // option that requires an argument, getopt_long will freak out.
+ // option that requires an argument, getopt_long_only will freak out.
input.AppendArgument ("<FAKE-VALUE>");
@@ -890,15 +963,17 @@ CommandObjectParsed::Execute (const char
cmd_args.ReplaceArgumentAtIndex (i, m_interpreter.ProcessEmbeddedScriptCommands (tmp_str));
}
- if (!CheckFlags(result))
- return false;
-
- if (!ParseOptions (cmd_args, result))
- return false;
-
+ if (CheckRequirements(result))
+ {
+ if (ParseOptions (cmd_args, result))
+ {
// Call the command-specific version of 'Execute', passing it the already processed arguments.
handled = DoExecute (cmd_args, result);
}
+ }
+
+ Cleanup();
+ }
return handled;
}
@@ -918,10 +993,10 @@ CommandObjectRaw::Execute (const char *a
}
if (!handled)
{
- if (!CheckFlags(result))
- return false;
- else
+ if (CheckRequirements(result))
handled = DoExecute (args_string, result);
+
+ Cleanup();
}
return handled;
}
@@ -944,6 +1019,7 @@ CommandObject::ArgumentTableEntry
CommandObject::g_arguments_data[] =
{
{ eArgTypeAddress, "address", CommandCompletions::eNoCompletion, { NULL, false }, "A valid address in the target program's execution space." },
+ { eArgTypeAddressOrExpression, "address-expression", CommandCompletions::eNoCompletion, { NULL, false }, "An expression that resolves to an address." },
{ eArgTypeAliasName, "alias-name", CommandCompletions::eNoCompletion, { NULL, false }, "The name of an abbreviation (alias) for a debugger command." },
{ eArgTypeAliasOptions, "options-for-aliased-command", CommandCompletions::eNoCompletion, { NULL, false }, "Command options to be used as part of an alias (abbreviation) definition. (See 'help commands alias' for more information.)" },
{ eArgTypeArchitecture, "arch", CommandCompletions::eArchitectureCompletion, { arch_helper, true }, "The architecture name, e.g. i386 or x86_64." },
@@ -955,6 +1031,7 @@ CommandObject::g_arguments_data[] =
{ eArgTypeCommandName, "cmd-name", CommandCompletions::eNoCompletion, { NULL, false }, "A debugger command (may be multiple words), without any options or arguments." },
{ eArgTypeCount, "count", CommandCompletions::eNoCompletion, { NULL, false }, "An unsigned integer." },
{ eArgTypeDirectoryName, "directory", CommandCompletions::eDiskDirectoryCompletion, { NULL, false }, "A directory name." },
+ { eArgTypeDisassemblyFlavor, "disassembly-flavor", CommandCompletions::eNoCompletion, { NULL, false }, "A disassembly flavor recognized by your disassembly plugin. Currently the only valid options are \"att\" and \"intel\" for Intel targets" },
{ eArgTypeEndAddress, "end-address", CommandCompletions::eNoCompletion, { NULL, false }, "Help text goes here." },
{ eArgTypeExpression, "expr", CommandCompletions::eNoCompletion, { NULL, false }, "Help text goes here." },
{ eArgTypeExpressionPath, "expr-path", CommandCompletions::eNoCompletion, { ExprPathHelpTextCallback, true }, NULL },
Modified: lldb/branches/windows/source/Interpreter/CommandObjectRegexCommand.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/windows/source/Interpreter/CommandObjectRegexCommand.cpp?rev=179679&r1=179678&r2=179679&view=diff
==============================================================================
--- lldb/branches/windows/source/Interpreter/CommandObjectRegexCommand.cpp (original)
+++ lldb/branches/windows/source/Interpreter/CommandObjectRegexCommand.cpp Wed Apr 17 03:38:48 2013
@@ -30,10 +30,12 @@ CommandObjectRegexCommand::CommandObject
const char *name,
const char *help,
const char *syntax,
- uint32_t max_matches
+ uint32_t max_matches,
+ uint32_t completion_type_mask
) :
CommandObjectRaw (interpreter, name, help, syntax),
m_max_matches (max_matches),
+ m_completion_type_mask (completion_type_mask),
m_entries ()
{
}
@@ -58,7 +60,9 @@ CommandObjectRegexCommand::DoExecute
EntryCollection::const_iterator pos, end = m_entries.end();
for (pos = m_entries.begin(); pos != end; ++pos)
{
- if (pos->regex.Execute (command, m_max_matches))
+ RegularExpression::Match regex_match(m_max_matches);
+
+ if (pos->regex.Execute (command, ®ex_match))
{
std::string new_command(pos->command);
std::string match_str;
@@ -66,7 +70,7 @@ CommandObjectRegexCommand::DoExecute
size_t idx, percent_var_idx;
for (uint32_t match_idx=1; match_idx <= m_max_matches; ++match_idx)
{
- if (pos->regex.GetMatchAtIndex (command, match_idx, match_str))
+ if (regex_match.GetMatchAtIndex (command, match_idx, match_str))
{
const int percent_var_len = ::snprintf (percent_var, sizeof(percent_var), "%%%u", match_idx);
for (idx = 0; (percent_var_idx = new_command.find(percent_var, idx)) != std::string::npos; )
@@ -80,7 +84,9 @@ CommandObjectRegexCommand::DoExecute
// Interpret the new command and return this as the result!
if (m_interpreter.GetExpandRegexAliases())
result.GetOutputStream().Printf("%s\n", new_command.c_str());
- return m_interpreter.HandleCommand(new_command.c_str(), eLazyBoolCalculate, result);
+ // Pass in true for "no context switching". The command that called us should have set up the context
+ // appropriately, we shouldn't have to redo that.
+ return m_interpreter.HandleCommand(new_command.c_str(), eLazyBoolCalculate, result, NULL, true, true);
}
}
result.SetStatus(eReturnStatusFailed);
@@ -112,3 +118,33 @@ CommandObjectRegexCommand::AddRegexComma
m_entries.pop_back();
return false;
}
+
+int
+CommandObjectRegexCommand::HandleCompletion (Args &input,
+ int &cursor_index,
+ int &cursor_char_position,
+ int match_start_point,
+ int max_return_elements,
+ bool &word_complete,
+ StringList &matches)
+{
+ if (m_completion_type_mask)
+ {
+ std::string completion_str (input.GetArgumentAtIndex (cursor_index), cursor_char_position);
+ CommandCompletions::InvokeCommonCompletionCallbacks (m_interpreter,
+ m_completion_type_mask,
+ completion_str.c_str(),
+ match_start_point,
+ max_return_elements,
+ NULL,
+ word_complete,
+ matches);
+ return matches.GetSize();
+ }
+ else
+ {
+ matches.Clear();
+ word_complete = false;
+ }
+ return 0;
+}
Modified: lldb/branches/windows/source/Interpreter/CommandObjectScript.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/windows/source/Interpreter/CommandObjectScript.cpp?rev=179679&r1=179678&r2=179679&view=diff
==============================================================================
--- lldb/branches/windows/source/Interpreter/CommandObjectScript.cpp (original)
+++ lldb/branches/windows/source/Interpreter/CommandObjectScript.cpp Wed Apr 17 03:38:48 2013
@@ -16,13 +16,14 @@
// Other libraries and framework includes
// Project includes
-#include "lldb/Core/DataVisualization.h"
#include "lldb/Core/Debugger.h"
-#include "lldb/Interpreter/Args.h"
+#include "lldb/DataFormatters/DataVisualization.h"
+
+#include "lldb/Interpreter/Args.h"
+#include "lldb/Interpreter/CommandInterpreter.h"
#include "lldb/Interpreter/CommandReturnObject.h"
#include "lldb/Interpreter/ScriptInterpreter.h"
-#include "lldb/Interpreter/CommandInterpreter.h"
using namespace lldb;
using namespace lldb_private;
@@ -50,6 +51,19 @@ CommandObjectScript::DoExecute
CommandReturnObject &result
)
{
+#ifdef LLDB_DISABLE_PYTHON
+ // if we ever support languages other than Python this simple #ifdef won't work
+ result.AppendError("your copy of LLDB does not support scripting.");
+ result.SetStatus (eReturnStatusFailed);
+ return false;
+#else
+ if (m_interpreter.GetDebugger().GetScriptLanguage() == lldb::eScriptLanguageNone)
+ {
+ result.AppendError("the script-lang setting is set to none - scripting not available");
+ result.SetStatus (eReturnStatusFailed);
+ return false;
+ }
+
ScriptInterpreter *script_interpreter = m_interpreter.GetScriptInterpreter ();
if (script_interpreter == NULL)
@@ -75,4 +89,5 @@ CommandObjectScript::DoExecute
result.SetStatus(eReturnStatusFailed);
return result.Succeeded();
+#endif
}
Modified: lldb/branches/windows/source/Interpreter/CommandReturnObject.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/windows/source/Interpreter/CommandReturnObject.cpp?rev=179679&r1=179678&r2=179679&view=diff
==============================================================================
--- lldb/branches/windows/source/Interpreter/CommandReturnObject.cpp (original)
+++ lldb/branches/windows/source/Interpreter/CommandReturnObject.cpp Wed Apr 17 03:38:48 2013
@@ -123,13 +123,10 @@ CommandReturnObject::AppendWarning (cons
// don't append "\n" to the end of it.
void
-CommandReturnObject::AppendRawWarning (const char *in_string, int len)
+CommandReturnObject::AppendRawWarning (const char *in_string)
{
- if (!in_string)
- return;
- if (len < 0)
- len = ::strlen (in_string);
- GetErrorStream().Printf("%*.*s", len, len, in_string);
+ if (in_string && in_string[0])
+ GetErrorStream().PutCString(in_string);
}
void
@@ -153,13 +150,10 @@ CommandReturnObject::SetError (const Err
// don't append "\n" to the end of it.
void
-CommandReturnObject::AppendRawError (const char *in_string, int len)
+CommandReturnObject::AppendRawError (const char *in_string)
{
- if (!in_string)
- return;
- if (len < 0)
- len = ::strlen (in_string);
- GetErrorStream().Printf ("%*.*s", len, len, in_string);
+ if (in_string && in_string[0])
+ GetErrorStream().PutCString(in_string);
}
void
Modified: lldb/branches/windows/source/Interpreter/OptionGroupFormat.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/windows/source/Interpreter/OptionGroupFormat.cpp?rev=179679&r1=179678&r2=179679&view=diff
==============================================================================
--- lldb/branches/windows/source/Interpreter/OptionGroupFormat.cpp (original)
+++ lldb/branches/windows/source/Interpreter/OptionGroupFormat.cpp Wed Apr 17 03:38:48 2013
@@ -7,6 +7,8 @@
//
//===----------------------------------------------------------------------===//
+#include "lldb/lldb-python.h"
+
#include "lldb/Interpreter/OptionGroupFormat.h"
// C Includes
@@ -205,6 +207,7 @@ OptionGroupFormat::SetOptionValue (Comma
bool
OptionGroupFormat::ParserGDBFormatLetter (CommandInterpreter &interpreter, char format_letter, Format &format, uint32_t &byte_size)
{
+ m_has_gdb_format = true;
switch (format_letter)
{
case 'o': format = eFormatOctal; m_prev_gdb_format = format_letter; return true;
@@ -242,4 +245,5 @@ OptionGroupFormat::OptionParsingStarting
m_format.Clear();
m_byte_size.Clear();
m_count.Clear();
+ m_has_gdb_format = false;
}
Modified: lldb/branches/windows/source/Interpreter/OptionGroupPlatform.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/windows/source/Interpreter/OptionGroupPlatform.cpp?rev=179679&r1=179678&r2=179679&view=diff
==============================================================================
--- lldb/branches/windows/source/Interpreter/OptionGroupPlatform.cpp (original)
+++ lldb/branches/windows/source/Interpreter/OptionGroupPlatform.cpp Wed Apr 17 03:38:48 2013
@@ -36,7 +36,7 @@ OptionGroupPlatform::CreatePlatformWithO
platform_sp = Platform::Create (m_platform_name.c_str(), error);
if (platform_sp)
{
- if (platform_arch.IsValid() && !platform_sp->IsCompatibleArchitecture(arch, &platform_arch))
+ if (platform_arch.IsValid() && !platform_sp->IsCompatibleArchitecture(arch, false, &platform_arch))
{
error.SetErrorStringWithFormat("platform '%s' doesn't support '%s'", platform_sp->GetName(), arch.GetTriple().getTriple().c_str());
platform_sp.reset();
@@ -135,7 +135,7 @@ OptionGroupPlatform::SetOptionValue (Com
m_sdk_build.SetCString (option_arg);
break;
- case 's':
+ case 'S':
m_sdk_sysroot.SetCString (option_arg);
break;
Modified: lldb/branches/windows/source/Interpreter/OptionGroupValueObjectDisplay.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/windows/source/Interpreter/OptionGroupValueObjectDisplay.cpp?rev=179679&r1=179678&r2=179679&view=diff
==============================================================================
--- lldb/branches/windows/source/Interpreter/OptionGroupValueObjectDisplay.cpp (original)
+++ lldb/branches/windows/source/Interpreter/OptionGroupValueObjectDisplay.cpp Wed Apr 17 03:38:48 2013
@@ -146,3 +146,36 @@ OptionGroupValueObjectDisplay::OptionPar
use_dynamic = lldb::eNoDynamicValues;
}
}
+
+ValueObject::DumpValueObjectOptions
+OptionGroupValueObjectDisplay::GetAsDumpOptions (bool objc_is_compact,
+ lldb::Format format,
+ lldb::TypeSummaryImplSP summary_sp)
+{
+ ValueObject::DumpValueObjectOptions options;
+ options.SetMaximumPointerDepth(ptr_depth);
+ if (use_objc)
+ options.SetShowSummary(false);
+ else
+ options.SetOmitSummaryDepth(no_summary_depth);
+ options.SetMaximumDepth(max_depth)
+ .SetShowTypes(show_types)
+ .SetShowLocation(show_location)
+ .SetUseObjectiveC(use_objc)
+ .SetUseDynamicType(use_dynamic)
+ .SetUseSyntheticValue(use_synth)
+ .SetFlatOutput(flat_output)
+ .SetIgnoreCap(ignore_cap)
+ .SetFormat(format)
+ .SetSummary(summary_sp);
+
+ if (objc_is_compact)
+ options.SetHideRootType(use_objc)
+ .SetHideName(use_objc)
+ .SetHideValue(use_objc);
+
+ if (be_raw)
+ options.SetRawDisplay(true);
+
+ return options;
+}
Modified: lldb/branches/windows/source/Interpreter/OptionGroupVariable.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/windows/source/Interpreter/OptionGroupVariable.cpp?rev=179679&r1=179678&r2=179679&view=diff
==============================================================================
--- lldb/branches/windows/source/Interpreter/OptionGroupVariable.cpp (original)
+++ lldb/branches/windows/source/Interpreter/OptionGroupVariable.cpp Wed Apr 17 03:38:48 2013
@@ -15,10 +15,10 @@
// C++ Includes
// Other libraries and framework includes
// Project includes
-#include "lldb/Core/DataVisualization.h"
#include "lldb/Core/Error.h"
-#include "lldb/Target/Target.h"
+#include "lldb/DataFormatters/DataVisualization.h"
#include "lldb/Interpreter/CommandInterpreter.h"
+#include "lldb/Target/Target.h"
#include "lldb/Utility/Utils.h"
using namespace lldb;
@@ -38,7 +38,8 @@ g_option_table[] =
{ LLDB_OPT_SET_2, false, "summary-string", 'z', required_argument, NULL, 0, eArgTypeName, "Specify a summary string to use to format the variable output."},
};
-Error OptionGroupVariableNamedSummaryValidator (const char* str,void*)
+static Error
+ValidateNamedSummary (const char* str, void*)
{
if (!str || !str[0])
return Error("must specify a valid named summary");
@@ -48,7 +49,8 @@ Error OptionGroupVariableNamedSummaryVal
return Error();
}
-Error OptionGroupVariableNamedSummaryStringValidator (const char* str,void*)
+static Error
+ValidateSummaryString (const char* str, void*)
{
if (!str || !str[0])
return Error("must specify a non-empty summary string");
@@ -58,8 +60,8 @@ Error OptionGroupVariableNamedSummaryStr
OptionGroupVariable::OptionGroupVariable (bool show_frame_options) :
OptionGroup(),
include_frame_options (show_frame_options),
- summary(OptionGroupVariableNamedSummaryValidator),
- summary_string(OptionGroupVariableNamedSummaryStringValidator)
+ summary(ValidateNamedSummary),
+ summary_string(ValidateSummaryString)
{
}
Modified: lldb/branches/windows/source/Interpreter/OptionValueArch.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/windows/source/Interpreter/OptionValueArch.cpp?rev=179679&r1=179678&r2=179679&view=diff
==============================================================================
--- lldb/branches/windows/source/Interpreter/OptionValueArch.cpp (original)
+++ lldb/branches/windows/source/Interpreter/OptionValueArch.cpp Wed Apr 17 03:38:48 2013
@@ -15,8 +15,8 @@
// C++ Includes
// Other libraries and framework includes
// Project includes
-#include "lldb/Core/FormatManager.h"
#include "lldb/Core/State.h"
+#include "lldb/DataFormatters/FormatManager.h"
#include "lldb/Interpreter/Args.h"
#include "lldb/Interpreter/CommandCompletions.h"
Modified: lldb/branches/windows/source/Interpreter/OptionValueDictionary.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/windows/source/Interpreter/OptionValueDictionary.cpp?rev=179679&r1=179678&r2=179679&view=diff
==============================================================================
--- lldb/branches/windows/source/Interpreter/OptionValueDictionary.cpp (original)
+++ lldb/branches/windows/source/Interpreter/OptionValueDictionary.cpp Wed Apr 17 03:38:48 2013
@@ -16,8 +16,8 @@
// Other libraries and framework includes
#include "llvm/ADT/StringRef.h"
// Project includes
-#include "lldb/Core/FormatManager.h"
#include "lldb/Core/State.h"
+#include "lldb/DataFormatters/FormatManager.h"
#include "lldb/Interpreter/Args.h"
#include "lldb/Interpreter/OptionValueString.h"
Modified: lldb/branches/windows/source/Interpreter/OptionValueFileSpec.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/windows/source/Interpreter/OptionValueFileSpec.cpp?rev=179679&r1=179678&r2=179679&view=diff
==============================================================================
--- lldb/branches/windows/source/Interpreter/OptionValueFileSpec.cpp (original)
+++ lldb/branches/windows/source/Interpreter/OptionValueFileSpec.cpp Wed Apr 17 03:38:48 2013
@@ -15,8 +15,8 @@
// C++ Includes
// Other libraries and framework includes
// Project includes
-#include "lldb/Core/FormatManager.h"
#include "lldb/Core/State.h"
+#include "lldb/DataFormatters/FormatManager.h"
#include "lldb/Interpreter/Args.h"
#include "lldb/Interpreter/CommandCompletions.h"
Modified: lldb/branches/windows/source/Interpreter/OptionValueFormat.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/windows/source/Interpreter/OptionValueFormat.cpp?rev=179679&r1=179678&r2=179679&view=diff
==============================================================================
--- lldb/branches/windows/source/Interpreter/OptionValueFormat.cpp (original)
+++ lldb/branches/windows/source/Interpreter/OptionValueFormat.cpp Wed Apr 17 03:38:48 2013
@@ -15,8 +15,8 @@
// C++ Includes
// Other libraries and framework includes
// Project includes
-#include "lldb/Core/FormatManager.h"
#include "lldb/Core/Stream.h"
+#include "lldb/DataFormatters/FormatManager.h"
#include "lldb/Interpreter/Args.h"
using namespace lldb;
Modified: lldb/branches/windows/source/Interpreter/OptionValueString.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/windows/source/Interpreter/OptionValueString.cpp?rev=179679&r1=179678&r2=179679&view=diff
==============================================================================
--- lldb/branches/windows/source/Interpreter/OptionValueString.cpp (original)
+++ lldb/branches/windows/source/Interpreter/OptionValueString.cpp Wed Apr 17 03:38:48 2013
@@ -55,6 +55,28 @@ OptionValueString::SetValueFromCString (
VarSetOperationType op)
{
Error error;
+
+ std::string value_str_no_quotes;
+ if (value_cstr)
+ {
+ switch (value_cstr[0])
+ {
+ case '"':
+ case '\'':
+ {
+ size_t len = strlen(value_cstr);
+ if (len <= 1 || value_cstr[len-1] != value_cstr[0])
+ {
+ error.SetErrorString("mismatched quotes");
+ return error;
+ }
+ value_str_no_quotes.assign (value_cstr + 1, len - 2);
+ value_cstr = value_str_no_quotes.c_str();
+ }
+ break;
+ }
+ }
+
switch (op)
{
case eVarSetOperationInvalid:
Modified: lldb/branches/windows/source/Interpreter/Options.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/windows/source/Interpreter/Options.cpp?rev=179679&r1=179678&r2=179679&view=diff
==============================================================================
--- lldb/branches/windows/source/Interpreter/Options.cpp (original)
+++ lldb/branches/windows/source/Interpreter/Options.cpp Wed Apr 17 03:38:48 2013
@@ -310,7 +310,7 @@ Options::GetLongOptions ()
}
}
- //getopt_long requires a NULL final entry in the table:
+ //getopt_long_only requires a NULL final entry in the table:
m_getopt_table[i].name = NULL;
m_getopt_table[i].has_arg = 0;
@@ -796,7 +796,7 @@ Options::HandleOptionCompletion
}
else if (opt_defs_index != OptionArgElement::eUnrecognizedArg)
{
- // We recognized it, if it an incomplete long option, complete it anyway (getopt_long is
+ // We recognized it, if it an incomplete long option, complete it anyway (getopt_long_only is
// happy with shortest unique string, but it's still a nice thing to do.) Otherwise return
// The string so the upper level code will know this is a full match and add the " ".
if (cur_opt_str && strlen (cur_opt_str) > 2
@@ -819,7 +819,7 @@ Options::HandleOptionCompletion
// FIXME - not handling wrong options yet:
// Check to see if they are writing a long option & complete it.
// I think we will only get in here if the long option table has two elements
- // that are not unique up to this point. getopt_long does shortest unique match
+ // that are not unique up to this point. getopt_long_only does shortest unique match
// for long options already.
if (cur_opt_str && strlen (cur_opt_str) > 2
Modified: lldb/branches/windows/source/Interpreter/PythonDataObjects.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/windows/source/Interpreter/PythonDataObjects.cpp?rev=179679&r1=179678&r2=179679&view=diff
==============================================================================
--- lldb/branches/windows/source/Interpreter/PythonDataObjects.cpp (original)
+++ lldb/branches/windows/source/Interpreter/PythonDataObjects.cpp Wed Apr 17 03:38:48 2013
@@ -22,294 +22,358 @@
#endif
#include "lldb/Interpreter/PythonDataObjects.h"
+#include "lldb/Interpreter/ScriptInterpreter.h"
using namespace lldb_private;
using namespace lldb;
-PythonDataObject::PythonDataObject (PyObject* object) :
- m_object(object)
+//----------------------------------------------------------------------
+// PythonObject
+//----------------------------------------------------------------------
+PythonObject::PythonObject (const lldb::ScriptInterpreterObjectSP &script_object_sp) :
+ m_py_obj (NULL)
{
+ if (script_object_sp)
+ Reset ((PyObject *)script_object_sp->GetObject());
}
-PythonDataObject::PythonDataObject () :
- m_object()
+//----------------------------------------------------------------------
+// PythonString
+//----------------------------------------------------------------------
+
+PythonString::PythonString (PyObject *py_obj) :
+ PythonObject(py_obj)
{
}
-PythonDataObject::~PythonDataObject ()
+PythonString::PythonString (const PythonObject &object) :
+ PythonObject(object.GetPythonObject())
{
}
-PythonDataString
-PythonDataObject::GetStringObject ()
+PythonString::PythonString (const lldb::ScriptInterpreterObjectSP &script_object_sp) :
+ PythonObject (script_object_sp)
{
- return PythonDataString(GetPythonObject());
}
-
-PythonDataInteger
-PythonDataObject::GetIntegerObject ()
+
+PythonString::PythonString (const char* string) :
+ PythonObject(PyString_FromString(string))
+{
+}
+
+PythonString::PythonString () :
+ PythonObject()
{
- return PythonDataInteger(GetPythonObject());
}
-PythonDataArray
-PythonDataObject::GetArrayObject()
+PythonString::~PythonString ()
{
- return PythonDataArray(GetPythonObject());
}
-PythonDataDictionary
-PythonDataObject::GetDictionaryObject()
+bool
+PythonString::Reset (PyObject *py_obj)
{
- return PythonDataDictionary(GetPythonObject());
+ if (py_obj && PyString_Check(py_obj))
+ return PythonObject::Reset(py_obj);
+
+ PythonObject::Reset(NULL);
+ return py_obj == NULL;
}
-PythonDataInteger::PythonDataInteger (bool create_empty) :
- m_object(create_empty ? PyInt_FromLong(0) : NULL)
+const char*
+PythonString::GetString() const
{
+ if (m_py_obj)
+ return PyString_AsString(m_py_obj);
+ return NULL;
}
-PythonDataInteger::PythonDataInteger (PyObject* object) :
- m_object(object)
+size_t
+PythonString::GetSize() const
{
- if (object && !PyInt_Check(GetPythonObject()))
- m_object.Reset();
+ if (m_py_obj)
+ return PyString_Size(m_py_obj);
+ return 0;
}
-PythonDataInteger::PythonDataInteger (int64_t value) :
- m_object(PyInt_FromLong(value))
+void
+PythonString::SetString (const char* string)
{
+ PythonObject::Reset(PyString_FromString(string));
}
+//----------------------------------------------------------------------
+// PythonInteger
+//----------------------------------------------------------------------
-PythonDataInteger::~PythonDataInteger ()
+PythonInteger::PythonInteger (PyObject *py_obj) :
+ PythonObject(py_obj)
{
}
-int64_t
-PythonDataInteger::GetInteger()
+PythonInteger::PythonInteger (const PythonObject &object) :
+ PythonObject(object.GetPythonObject())
{
- if (m_object)
- return PyInt_AsLong(GetPythonObject());
- else
- return UINT64_MAX;
}
-void
-PythonDataInteger::SetInteger (int64_t value)
+PythonInteger::PythonInteger (const lldb::ScriptInterpreterObjectSP &script_object_sp) :
+ PythonObject (script_object_sp)
{
- m_object.Reset(PyInt_FromLong(value));
}
-PythonDataString::PythonDataString (bool create_empty) :
- m_object(create_empty ? PyString_FromString("") : NULL)
+PythonInteger::PythonInteger (int64_t value) :
+ PythonObject(PyInt_FromLong(value))
{
}
-PythonDataString::PythonDataString (PyObject* object) :
- m_object(object)
+
+PythonInteger::~PythonInteger ()
{
- if (object && !PyString_Check(GetPythonObject()))
- m_object.Reset();
}
-PythonDataString::PythonDataString (const char* string) :
- m_object(PyString_FromString(string))
+bool
+PythonInteger::Reset (PyObject *py_obj)
{
+ if (py_obj && PyInt_Check(py_obj))
+ return PythonObject::Reset(py_obj);
+
+ PythonObject::Reset(NULL);
+ return py_obj == NULL;
}
-PythonDataString::~PythonDataString ()
+int64_t
+PythonInteger::GetInteger()
{
+ if (m_py_obj)
+ return PyInt_AsLong(m_py_obj);
+ else
+ return UINT64_MAX;
}
-const char*
-PythonDataString::GetString() const
+void
+PythonInteger::SetInteger (int64_t value)
{
- if (m_object)
- return PyString_AsString(GetPythonObject());
- return NULL;
+ PythonObject::Reset(PyInt_FromLong(value));
}
-size_t
-PythonDataString::GetSize() const
+//----------------------------------------------------------------------
+// PythonList
+//----------------------------------------------------------------------
+
+PythonList::PythonList () :
+ PythonObject(PyList_New(0))
{
- if (m_object)
- return PyString_Size(GetPythonObject());
- return 0;
}
-void
-PythonDataString::SetString (const char* string)
+PythonList::PythonList (uint32_t count) :
+ PythonObject(PyList_New(count))
+{
+}
+
+PythonList::PythonList (PyObject *py_obj) :
+ PythonObject(py_obj)
{
- m_object.Reset(PyString_FromString(string));
}
-PythonDataArray::PythonDataArray (bool create_empty) :
- m_object(create_empty ? PyList_New(0) : NULL)
+
+PythonList::PythonList (const PythonObject &object) :
+ PythonObject(object.GetPythonObject())
{
}
-PythonDataArray::PythonDataArray (uint32_t count) :
- m_object(PyList_New(count))
+PythonList::PythonList (const lldb::ScriptInterpreterObjectSP &script_object_sp) :
+ PythonObject (script_object_sp)
{
}
-PythonDataArray::PythonDataArray (PyObject* object) :
- m_object(object)
+PythonList::~PythonList ()
{
- if (object && !PyList_Check(GetPythonObject()))
- m_object.Reset();
}
-PythonDataArray::~PythonDataArray ()
+bool
+PythonList::Reset (PyObject *py_obj)
{
+ if (py_obj && PyList_Check(py_obj))
+ return PythonObject::Reset(py_obj);
+
+ PythonObject::Reset(NULL);
+ return py_obj == NULL;
}
uint32_t
-PythonDataArray::GetSize()
+PythonList::GetSize()
{
- if (m_object)
- return PyList_GET_SIZE(GetPythonObject());
+ if (m_py_obj)
+ return PyList_GET_SIZE(m_py_obj);
return 0;
}
-PythonDataObject
-PythonDataArray::GetItemAtIndex (uint32_t index)
+PythonObject
+PythonList::GetItemAtIndex (uint32_t index)
{
- if (m_object)
- return PythonDataObject(PyList_GetItem(GetPythonObject(), index));
+ if (m_py_obj)
+ return PythonObject(PyList_GetItem(m_py_obj, index));
return NULL;
}
void
-PythonDataArray::SetItemAtIndex (uint32_t index, const PythonDataObject & object)
+PythonList::SetItemAtIndex (uint32_t index, const PythonObject & object)
{
- if (m_object && object)
- PyList_SetItem(GetPythonObject(), index, object.GetPythonObject());
+ if (m_py_obj && object)
+ PyList_SetItem(m_py_obj, index, object.GetPythonObject());
}
void
-PythonDataArray::AppendItem (const PythonDataObject &object)
+PythonList::AppendItem (const PythonObject &object)
+{
+ if (m_py_obj && object)
+ PyList_Append(m_py_obj, object.GetPythonObject());
+}
+
+//----------------------------------------------------------------------
+// PythonDictionary
+//----------------------------------------------------------------------
+
+PythonDictionary::PythonDictionary () :
+ PythonObject(PyDict_New())
+{
+}
+
+PythonDictionary::PythonDictionary (PyObject *py_obj) :
+ PythonObject(py_obj)
+{
+}
+
+
+PythonDictionary::PythonDictionary (const PythonObject &object) :
+ PythonObject(object.GetPythonObject())
{
- if (m_object && object)
- PyList_Append(GetPythonObject(), object.GetPythonObject());
}
-PythonDataDictionary::PythonDataDictionary (bool create_empty) :
- m_object(create_empty ? PyDict_New() : NULL)
+PythonDictionary::PythonDictionary (const lldb::ScriptInterpreterObjectSP &script_object_sp) :
+ PythonObject (script_object_sp)
{
}
-PythonDataDictionary::PythonDataDictionary (PyObject* object) :
- m_object(object)
+PythonDictionary::~PythonDictionary ()
{
- if (object && !PyDict_Check(GetPythonObject()))
- m_object.Reset();
}
-PythonDataDictionary::~PythonDataDictionary ()
+bool
+PythonDictionary::Reset (PyObject *py_obj)
{
+ if (py_obj && PyDict_Check(py_obj))
+ return PythonObject::Reset(py_obj);
+
+ PythonObject::Reset(NULL);
+ return py_obj == NULL;
}
uint32_t
-PythonDataDictionary::GetSize()
+PythonDictionary::GetSize()
{
- if (m_object)
- return PyDict_Size(GetPythonObject());
+ if (m_py_obj)
+ return PyDict_Size(m_py_obj);
return 0;
}
-PythonDataObject
-PythonDataDictionary::GetItemForKey (const char *key) const
+PythonObject
+PythonDictionary::GetItemForKey (const char *key) const
{
if (key && key[0])
{
- PythonDataString python_key(key);
+ PythonString python_key(key);
return GetItemForKey(python_key);
}
return NULL;
}
-PythonDataObject
-PythonDataDictionary::GetItemForKey (const PythonDataString &key) const
+PythonObject
+PythonDictionary::GetItemForKey (const PythonString &key) const
{
- if (m_object && key)
- return PythonDataObject(PyDict_GetItem(GetPythonObject(), key.GetPythonObject()));
- return PythonDataObject();
+ if (m_py_obj && key)
+ return PythonObject(PyDict_GetItem(m_py_obj, key.GetPythonObject()));
+ return PythonObject();
}
const char *
-PythonDataDictionary::GetItemForKeyAsString (const PythonDataString &key, const char *fail_value) const
+PythonDictionary::GetItemForKeyAsString (const PythonString &key, const char *fail_value) const
{
- if (m_object && key)
+ if (m_py_obj && key)
{
- PyObject *object = PyDict_GetItem(GetPythonObject(), key.GetPythonObject());
- if (object && PyString_Check(object))
- return PyString_AsString(object);
+ PyObject *py_obj = PyDict_GetItem(m_py_obj, key.GetPythonObject());
+ if (py_obj && PyString_Check(py_obj))
+ return PyString_AsString(py_obj);
}
return fail_value;
}
int64_t
-PythonDataDictionary::GetItemForKeyAsInteger (const PythonDataString &key, int64_t fail_value) const
+PythonDictionary::GetItemForKeyAsInteger (const PythonString &key, int64_t fail_value) const
{
- if (m_object && key)
+ if (m_py_obj && key)
{
- PyObject *object = PyDict_GetItem(GetPythonObject(), key.GetPythonObject());
- if (object && PyInt_Check(object))
- return PyInt_AsLong(object);
+ PyObject *py_obj = PyDict_GetItem(m_py_obj, key.GetPythonObject());
+ if (py_obj)
+ {
+ if (PyInt_Check(py_obj))
+ return PyInt_AsLong(py_obj);
+
+ if (PyLong_Check(py_obj))
+ return PyLong_AsLong(py_obj);
+ }
}
return fail_value;
}
-PythonDataArray
-PythonDataDictionary::GetKeys () const
+PythonList
+PythonDictionary::GetKeys () const
{
- if (m_object)
- return PythonDataArray(PyDict_Keys(GetPythonObject()));
- return PythonDataArray();
+ if (m_py_obj)
+ return PythonList(PyDict_Keys(m_py_obj));
+ return PythonList();
}
-PythonDataString
-PythonDataDictionary::GetKeyAtPosition (uint32_t pos) const
+PythonString
+PythonDictionary::GetKeyAtPosition (uint32_t pos) const
{
PyObject *key, *value;
Py_ssize_t pos_iter = 0;
- if (m_object)
+ if (m_py_obj)
{
- while (PyDict_Next(GetPythonObject(), &pos_iter, &key, &value))
+ while (PyDict_Next(m_py_obj, &pos_iter, &key, &value))
{
if (pos-- == 0)
- return PythonDataString(key);
+ return PythonString(key);
}
}
- return PythonDataString();
+ return PythonString();
}
-PythonDataObject
-PythonDataDictionary::GetValueAtPosition (uint32_t pos) const
+PythonObject
+PythonDictionary::GetValueAtPosition (uint32_t pos) const
{
PyObject *key, *value;
Py_ssize_t pos_iter = 0;
- if (!m_object)
+ if (!m_py_obj)
return NULL;
- while (PyDict_Next(GetPythonObject(), &pos_iter, &key, &value)) {
+ while (PyDict_Next(m_py_obj, &pos_iter, &key, &value)) {
if (pos-- == 0)
- return PythonDataObject(value);
+ return PythonObject(value);
}
- return PythonDataObject();
+ return PythonObject();
}
void
-PythonDataDictionary::SetItemForKey (const PythonDataString &key, const PythonDataObject &value)
+PythonDictionary::SetItemForKey (const PythonString &key, const PythonObject &value)
{
- if (m_object && key && value)
- PyDict_SetItem(GetPythonObject(), key.GetPythonObject(), value.GetPythonObject());
+ if (m_py_obj && key && value)
+ PyDict_SetItem(m_py_obj, key.GetPythonObject(), value.GetPythonObject());
}
#endif
Modified: lldb/branches/windows/source/Interpreter/ScriptInterpreter.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/windows/source/Interpreter/ScriptInterpreter.cpp?rev=179679&r1=179678&r2=179679&view=diff
==============================================================================
--- lldb/branches/windows/source/Interpreter/ScriptInterpreter.cpp (original)
+++ lldb/branches/windows/source/Interpreter/ScriptInterpreter.cpp Wed Apr 17 03:38:48 2013
@@ -81,6 +81,12 @@ ScriptInterpreter::LanguageToString (lld
return return_value;
}
+std::auto_ptr<ScriptInterpreterLocker>
+ScriptInterpreter::AcquireInterpreterLock ()
+{
+ return std::auto_ptr<ScriptInterpreterLocker>(new ScriptInterpreterLocker());
+}
+
void
ScriptInterpreter::InitializeInterpreter (SWIGInitCallback python_swig_init_callback)
{
Modified: lldb/branches/windows/source/Interpreter/ScriptInterpreterPython.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/windows/source/Interpreter/ScriptInterpreterPython.cpp?rev=179679&r1=179678&r2=179679&view=diff
==============================================================================
--- lldb/branches/windows/source/Interpreter/ScriptInterpreterPython.cpp (original)
+++ lldb/branches/windows/source/Interpreter/ScriptInterpreterPython.cpp Wed Apr 17 03:38:48 2013
@@ -64,72 +64,65 @@ static ScriptInterpreter::SWIGPythonCrea
// on linkage-time resolution because the SWIG stuff and this file
// get built at different times
extern "C" bool
-LLDBSwigPythonBreakpointCallbackFunction
-(
- const char *python_function_name,
- const char *session_dictionary_name,
- const lldb::StackFrameSP& sb_frame,
- const lldb::BreakpointLocationSP& sb_bp_loc
- );
+LLDBSwigPythonBreakpointCallbackFunction (const char *python_function_name,
+ const char *session_dictionary_name,
+ const lldb::StackFrameSP& sb_frame,
+ const lldb::BreakpointLocationSP& sb_bp_loc);
extern "C" bool
-LLDBSwigPythonWatchpointCallbackFunction
-(
- const char *python_function_name,
- const char *session_dictionary_name,
- const lldb::StackFrameSP& sb_frame,
- const lldb::WatchpointSP& sb_wp
- );
+LLDBSwigPythonWatchpointCallbackFunction (const char *python_function_name,
+ const char *session_dictionary_name,
+ const lldb::StackFrameSP& sb_frame,
+ const lldb::WatchpointSP& sb_wp);
extern "C" bool
-LLDBSwigPythonCallTypeScript
-(
- const char *python_function_name,
- void *session_dictionary,
- const lldb::ValueObjectSP& valobj_sp,
- void** pyfunct_wrapper,
- std::string& retval
- );
+LLDBSwigPythonCallTypeScript (const char *python_function_name,
+ void *session_dictionary,
+ const lldb::ValueObjectSP& valobj_sp,
+ void** pyfunct_wrapper,
+ std::string& retval);
extern "C" void*
-LLDBSwigPythonCreateSyntheticProvider
-(
- const std::string python_class_name,
- const char *session_dictionary_name,
- const lldb::ValueObjectSP& valobj_sp
- );
+LLDBSwigPythonCreateSyntheticProvider (const char *python_class_name,
+ const char *session_dictionary_name,
+ const lldb::ValueObjectSP& valobj_sp);
-extern "C" uint32_t LLDBSwigPython_CalculateNumChildren (void *implementor);
-extern "C" void* LLDBSwigPython_GetChildAtIndex (void *implementor, uint32_t idx);
-extern "C" int LLDBSwigPython_GetIndexOfChildWithName (void *implementor, const char* child_name);
-extern "C" void* LLDBSWIGPython_CastPyObjectToSBValue (void* data);
-extern "C" bool LLDBSwigPython_UpdateSynthProviderInstance (void* implementor);
-extern "C" bool LLDBSwigPython_MightHaveChildrenSynthProviderInstance (void* implementor);
+extern "C" uint32_t
+LLDBSwigPython_CalculateNumChildren (void *implementor);
-extern "C" bool LLDBSwigPythonCallCommand
-(
- const char *python_function_name,
- const char *session_dictionary_name,
- lldb::DebuggerSP& debugger,
- const char* args,
- std::string& err_msg,
- lldb_private::CommandReturnObject& cmd_retobj
- );
+extern "C" void *
+LLDBSwigPython_GetChildAtIndex (void *implementor, uint32_t idx);
-extern "C" bool LLDBSwigPythonCallModuleInit
-(
- const std::string python_module_name,
- const char *session_dictionary_name,
- lldb::DebuggerSP& debugger
- );
+extern "C" int
+LLDBSwigPython_GetIndexOfChildWithName (void *implementor, const char* child_name);
-extern "C" void* LLDBSWIGPythonCreateOSPlugin
-(
- const std::string python_class_name,
- const char *session_dictionary_name,
- const lldb::ProcessSP& process_sp
-);
+extern "C" void *
+LLDBSWIGPython_CastPyObjectToSBValue (void* data);
+
+extern "C" bool
+LLDBSwigPython_UpdateSynthProviderInstance (void* implementor);
+
+extern "C" bool
+LLDBSwigPython_MightHaveChildrenSynthProviderInstance (void* implementor);
+
+extern "C" bool
+LLDBSwigPythonCallCommand (const char *python_function_name,
+ const char *session_dictionary_name,
+ lldb::DebuggerSP& debugger,
+ const char* args,
+ std::string& err_msg,
+ lldb_private::CommandReturnObject& cmd_retobj);
+
+extern "C" bool
+LLDBSwigPythonCallModuleInit (const char *python_module_name,
+ const char *session_dictionary_name,
+ lldb::DebuggerSP& debugger);
+
+extern "C" void*
+LLDBSWIGPythonCreateOSPlugin (const char *python_class_name,
+ const char *session_dictionary_name,
+ const lldb::ProcessSP& process_sp);
static int
_check_and_flush (FILE *stream)
@@ -142,7 +135,8 @@ ScriptInterpreterPython::Locker::Locker
uint16_t on_entry,
uint16_t on_leave,
FILE* wait_msg_handle) :
- m_need_session( (on_leave & TearDownSession) == TearDownSession ),
+ ScriptInterpreterLocker (),
+ m_teardown_session( (on_leave & TearDownSession) == TearDownSession ),
m_python_interpreter(py_interpreter),
m_tmp_fh(wait_msg_handle)
{
@@ -151,13 +145,19 @@ ScriptInterpreterPython::Locker::Locker
DoAcquireLock();
if ((on_entry & InitSession) == InitSession)
- DoInitSession((on_entry & InitGlobals) == InitGlobals);
+ {
+ if (DoInitSession((on_entry & InitGlobals) == InitGlobals) == false)
+ {
+ // Don't teardown the session if we didn't init it.
+ m_teardown_session = false;
+ }
+ }
}
bool
ScriptInterpreterPython::Locker::DoAcquireLock()
{
- LogSP log (lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_SCRIPT | LIBLLDB_LOG_VERBOSE));
+ Log *log (lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_SCRIPT | LIBLLDB_LOG_VERBOSE));
m_GILState = PyGILState_Ensure();
if (log)
log->Printf("Ensured PyGILState. Previous state = %slocked\n", m_GILState == PyGILState_UNLOCKED ? "un" : "");
@@ -169,14 +169,13 @@ ScriptInterpreterPython::Locker::DoInitS
{
if (!m_python_interpreter)
return false;
- m_python_interpreter->EnterSession (init_lldb_globals);
- return true;
+ return m_python_interpreter->EnterSession (init_lldb_globals);
}
bool
ScriptInterpreterPython::Locker::DoFreeLock()
{
- LogSP log (lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_SCRIPT | LIBLLDB_LOG_VERBOSE));
+ Log *log (lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_SCRIPT | LIBLLDB_LOG_VERBOSE));
if (log)
log->Printf("Releasing PyGILState. Returning to state = %slocked\n", m_GILState == PyGILState_UNLOCKED ? "un" : "");
PyGILState_Release(m_GILState);
@@ -194,7 +193,7 @@ ScriptInterpreterPython::Locker::DoTearD
ScriptInterpreterPython::Locker::~Locker()
{
- if (m_need_session)
+ if (m_teardown_session)
DoTearDownSession();
DoFreeLock();
}
@@ -261,17 +260,14 @@ ScriptInterpreterPython::PythonInputRead
}
size_t
-ScriptInterpreterPython::PythonInputReaderManager::InputReaderCallback
-(
- void *baton,
- InputReader &reader,
- InputReaderAction notification,
- const char *bytes,
- size_t bytes_len
- )
+ScriptInterpreterPython::PythonInputReaderManager::InputReaderCallback (void *baton,
+ InputReader &reader,
+ InputReaderAction notification,
+ const char *bytes,
+ size_t bytes_len)
{
lldb::thread_t embedded_interpreter_thread;
- LogSP log (lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_SCRIPT));
+ Log *log (lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_SCRIPT));
if (baton == NULL)
return 0;
@@ -371,22 +367,22 @@ ScriptInterpreterPython::PythonInputRead
break;
case eInputReaderInterrupt:
- {
- PyThreadState* state = _PyThreadState_Current;
- if (!state)
- state = script_interpreter->m_command_thread_state;
- if (state)
- {
- long tid = state->thread_id;
- _PyThreadState_Current = state;
- int num_threads = PyThreadState_SetAsyncExc(tid, PyExc_KeyboardInterrupt);
- if (log)
- log->Printf("ScriptInterpreterPython::NonInteractiveInputReaderCallback, eInputReaderInterrupt, tid = %ld, num_threads = %d, state = %p",
- tid,num_threads,state);
+ {
+ PyThreadState* state = _PyThreadState_Current;
+ if (!state)
+ state = script_interpreter->m_command_thread_state;
+ if (state)
+ {
+ long tid = state->thread_id;
+ _PyThreadState_Current = state;
+ int num_threads = PyThreadState_SetAsyncExc(tid, PyExc_KeyboardInterrupt);
+ if (log)
+ log->Printf("ScriptInterpreterPython::NonInteractiveInputReaderCallback, eInputReaderInterrupt, tid = %ld, num_threads = %d, state = %p",
+ tid,num_threads,state);
+ }
+ else if (log)
+ log->Printf("ScriptInterpreterPython::NonInteractiveInputReaderCallback, eInputReaderInterrupt, state = NULL");
}
- else if (log)
- log->Printf("ScriptInterpreterPython::NonInteractiveInputReaderCallback, eInputReaderInterrupt, state = NULL");
- }
break;
case eInputReaderEndOfFile:
@@ -411,36 +407,30 @@ ScriptInterpreterPython::PythonInputRead
bytes_len);
reader.SetIsDone (true);
}
-
break;
case eInputReaderDone:
- {
- StreamString run_string;
- char error_str[1024];
- const char *pty_slave_name = script_interpreter->m_embedded_thread_pty.GetSlaveName (error_str, sizeof (error_str));
- if (pty_slave_name != NULL && PyThreadState_GetDict() != NULL)
{
- ScriptInterpreterPython::Locker locker(script_interpreter,
- ScriptInterpreterPython::Locker::AcquireLock | ScriptInterpreterPython::Locker::InitSession,
- ScriptInterpreterPython::Locker::FreeAcquiredLock);
- run_string.Printf ("run_one_line (%s, 'sys.stdin = save_stdin')", script_interpreter->m_dictionary_name.c_str());
- PyRun_SimpleString (run_string.GetData());
- run_string.Clear();
+ StreamString run_string;
+ char error_str[1024];
+ const char *pty_slave_name = script_interpreter->m_embedded_thread_pty.GetSlaveName (error_str, sizeof (error_str));
+ if (pty_slave_name != NULL && PyThreadState_GetDict() != NULL)
+ {
+ ScriptInterpreterPython::Locker locker(script_interpreter,
+ ScriptInterpreterPython::Locker::AcquireLock,
+ ScriptInterpreterPython::Locker::FreeAcquiredLock);
+ run_string.Printf ("run_one_line (%s, 'sys.stdin = save_stdin; sys.stderr = save_stderr')", script_interpreter->m_dictionary_name.c_str());
+ PyRun_SimpleString (run_string.GetData());
+ run_string.Clear();
+ }
+ // Restore terminal settings if they were validly saved
+ if (log)
+ log->Printf ("ScriptInterpreterPython::NonInteractiveInputReaderCallback, Done, closing down input reader.");
- run_string.Printf ("run_one_line (%s, 'sys.stderr = save_stderr')", script_interpreter->m_dictionary_name.c_str());
- PyRun_SimpleString (run_string.GetData());
- run_string.Clear();
- }
- }
-
- // Restore terminal settings if they were validly saved
- if (log)
- log->Printf ("ScriptInterpreterPython::NonInteractiveInputReaderCallback, Done, closing down input reader.");
-
- script_interpreter->RestoreTerminalState ();
-
- script_interpreter->m_embedded_thread_pty.CloseMasterFileDescriptor();
+ script_interpreter->RestoreTerminalState ();
+
+ script_interpreter->m_embedded_thread_pty.CloseMasterFileDescriptor();
+ }
break;
}
@@ -500,7 +490,7 @@ ScriptInterpreterPython::ScriptInterpret
// WARNING: temporary code that loads Cocoa formatters - this should be done on a per-platform basis rather than loading the whole set
// and letting the individual formatter classes exploit APIs to check whether they can/cannot do their task
run_string.Clear();
- run_string.Printf ("run_one_line (%s, 'import lldb.runtime.objc, lldb.formatters, lldb.formatters.objc, lldb.formatters.cpp, pydoc')", m_dictionary_name.c_str());
+ run_string.Printf ("run_one_line (%s, 'import lldb.formatters, lldb.formatters.cpp, pydoc')", m_dictionary_name.c_str());
PyRun_SimpleString (run_string.GetData());
int new_count = Debugger::TestDebuggerRefCount();
@@ -593,6 +583,10 @@ ScriptInterpreterPython::RestoreTerminal
void
ScriptInterpreterPython::LeaveSession ()
{
+ Log *log (lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_SCRIPT));
+ if (log)
+ log->PutCString("ScriptInterpreterPython::LeaveSession()");
+
// checking that we have a valid thread state - since we use our own threading and locking
// in some (rare) cases during cleanup Python may end up believing we have no thread state
// and PyImport_AddModule will crash if that is the case - since that seems to only happen
@@ -617,14 +611,22 @@ ScriptInterpreterPython::LeaveSession ()
m_session_is_active = false;
}
-void
+bool
ScriptInterpreterPython::EnterSession (bool init_lldb_globals)
{
// If we have already entered the session, without having officially 'left' it, then there is no need to
// 'enter' it again.
-
+ Log *log (lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_SCRIPT));
if (m_session_is_active)
- return;
+ {
+ if (log)
+ log->Printf("ScriptInterpreterPython::EnterSession(init_lldb_globals=%i) session is already active, returning without doing anything", init_lldb_globals);
+ return false;
+ }
+
+ if (log)
+ log->Printf("ScriptInterpreterPython::EnterSession(init_lldb_globals=%i)", init_lldb_globals);
+
m_session_is_active = true;
@@ -667,6 +669,8 @@ ScriptInterpreterPython::EnterSession (b
if (PyErr_Occurred())
PyErr_Clear ();
+
+ return true;
}
static PyObject*
@@ -740,7 +744,7 @@ ScriptInterpreterPython::ExecuteOneLine
Locker locker(this,
ScriptInterpreterPython::Locker::AcquireLock | ScriptInterpreterPython::Locker::InitSession | (options.GetSetLLDBGlobals() ? ScriptInterpreterPython::Locker::InitGlobals : 0),
- ScriptInterpreterPython::Locker::FreeAcquiredLock | (options.GetSetLLDBGlobals() ? ScriptInterpreterPython::Locker::TearDownSession : 0));
+ ScriptInterpreterPython::Locker::FreeAcquiredLock | ScriptInterpreterPython::Locker::TearDownSession);
bool success = false;
@@ -829,7 +833,7 @@ ScriptInterpreterPython::InputReaderCall
)
{
lldb::thread_t embedded_interpreter_thread;
- LogSP log (lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_SCRIPT));
+ Log *log (lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_SCRIPT));
if (baton == NULL)
return 0;
@@ -861,9 +865,7 @@ ScriptInterpreterPython::InputReaderCall
{
ScriptInterpreterPython::Locker locker(script_interpreter,
- ScriptInterpreterPython::Locker::AcquireLock
- | ScriptInterpreterPython::Locker::InitSession
- | ScriptInterpreterPython::Locker::InitGlobals,
+ ScriptInterpreterPython::Locker::AcquireLock | ScriptInterpreterPython::Locker::InitSession | ScriptInterpreterPython::Locker::InitGlobals,
ScriptInterpreterPython::Locker::FreeAcquiredLock);
}
@@ -907,11 +909,9 @@ ScriptInterpreterPython::InputReaderCall
case eInputReaderReactivate:
{
- ScriptInterpreterPython::Locker locker(script_interpreter,
- ScriptInterpreterPython::Locker::AcquireLock
- | ScriptInterpreterPython::Locker::InitSession
- | ScriptInterpreterPython::Locker::InitGlobals,
- ScriptInterpreterPython::Locker::FreeAcquiredLock);
+ ScriptInterpreterPython::Locker locker (script_interpreter,
+ ScriptInterpreterPython::Locker::AcquireLock | ScriptInterpreterPython::Locker::InitSession,
+ ScriptInterpreterPython::Locker::FreeAcquiredLock);
}
break;
@@ -1015,10 +1015,8 @@ ScriptInterpreterPython::ExecuteOneLineW
{
Locker locker(this,
- ScriptInterpreterPython::Locker::AcquireLock
- | ScriptInterpreterPython::Locker::InitSession
- | (options.GetSetLLDBGlobals() ? ScriptInterpreterPython::Locker::InitGlobals : 0),
- ScriptInterpreterPython::Locker::FreeAcquiredLock | (options.GetSetLLDBGlobals() ? ScriptInterpreterPython::Locker::TearDownSession : 0));
+ ScriptInterpreterPython::Locker::AcquireLock | ScriptInterpreterPython::Locker::InitSession | (options.GetSetLLDBGlobals() ? ScriptInterpreterPython::Locker::InitGlobals : 0),
+ ScriptInterpreterPython::Locker::FreeAcquiredLock | ScriptInterpreterPython::Locker::TearDownSession);
PyObject *py_return = NULL;
PyObject *mainmod = PyImport_AddModule ("__main__");
@@ -1184,10 +1182,8 @@ ScriptInterpreterPython::ExecuteMultiple
Locker locker(this,
- ScriptInterpreterPython::Locker::AcquireLock
- | ScriptInterpreterPython::Locker::InitSession
- | (options.GetSetLLDBGlobals() ? ScriptInterpreterPython::Locker::InitGlobals : 0),
- ScriptInterpreterPython::Locker::FreeAcquiredLock | (options.GetSetLLDBGlobals() ? ScriptInterpreterPython::Locker::TearDownSession : 0));
+ ScriptInterpreterPython::Locker::AcquireLock | ScriptInterpreterPython::Locker::InitSession | (options.GetSetLLDBGlobals() ? ScriptInterpreterPython::Locker::InitGlobals : 0),
+ ScriptInterpreterPython::Locker::FreeAcquiredLock | ScriptInterpreterPython::Locker::TearDownSession);
bool success = false;
PyObject *py_return = NULL;
@@ -1726,10 +1722,9 @@ ScriptInterpreterPython::GenerateTypeSyn
}
lldb::ScriptInterpreterObjectSP
-ScriptInterpreterPython::CreateOSPlugin (std::string class_name,
- lldb::ProcessSP process_sp)
+ScriptInterpreterPython::OSPlugin_CreatePluginObject (const char *class_name, lldb::ProcessSP process_sp)
{
- if (class_name.empty())
+ if (class_name == NULL || class_name[0] == '\0')
return lldb::ScriptInterpreterObjectSP();
if (!process_sp)
@@ -1748,16 +1743,16 @@ ScriptInterpreterPython::CreateOSPlugin
}
lldb::ScriptInterpreterObjectSP
-ScriptInterpreterPython::OSPlugin_QueryForRegisterInfo (lldb::ScriptInterpreterObjectSP object)
+ScriptInterpreterPython::OSPlugin_RegisterInfo (lldb::ScriptInterpreterObjectSP os_plugin_object_sp)
{
Locker py_lock(this,Locker::AcquireLock,Locker::FreeLock);
static char callee_name[] = "get_register_info";
- if (!object)
+ if (!os_plugin_object_sp)
return lldb::ScriptInterpreterObjectSP();
- PyObject* implementor = (PyObject*)object->GetObject();
+ PyObject* implementor = (PyObject*)os_plugin_object_sp->GetObject();
if (implementor == NULL || implementor == Py_None)
return lldb::ScriptInterpreterObjectSP();
@@ -1807,16 +1802,16 @@ ScriptInterpreterPython::OSPlugin_QueryF
}
lldb::ScriptInterpreterObjectSP
-ScriptInterpreterPython::OSPlugin_QueryForThreadsInfo (lldb::ScriptInterpreterObjectSP object)
+ScriptInterpreterPython::OSPlugin_ThreadsInfo (lldb::ScriptInterpreterObjectSP os_plugin_object_sp)
{
Locker py_lock(this,Locker::AcquireLock,Locker::FreeLock);
static char callee_name[] = "get_thread_info";
- if (!object)
+ if (!os_plugin_object_sp)
return lldb::ScriptInterpreterObjectSP();
- PyObject* implementor = (PyObject*)object->GetObject();
+ PyObject* implementor = (PyObject*)os_plugin_object_sp->GetObject();
if (implementor == NULL || implementor == Py_None)
return lldb::ScriptInterpreterObjectSP();
@@ -1865,19 +1860,45 @@ ScriptInterpreterPython::OSPlugin_QueryF
return MakeScriptObject(py_return);
}
+// GetPythonValueFormatString provides a system independent type safe way to
+// convert a variable's type into a python value format. Python value formats
+// are defined in terms of builtin C types and could change from system to
+// as the underlying typedef for uint* types, size_t, off_t and other values
+// change.
+
+template <typename T>
+const char *GetPythonValueFormatString(T t)
+{
+ assert(!"Unhandled type passed to GetPythonValueFormatString(T), make a specialization of GetPythonValueFormatString() to support this type.");
+ return NULL;
+}
+template <> const char *GetPythonValueFormatString (char *) { return "s"; }
+template <> const char *GetPythonValueFormatString (char) { return "b"; }
+template <> const char *GetPythonValueFormatString (unsigned char) { return "B"; }
+template <> const char *GetPythonValueFormatString (short) { return "h"; }
+template <> const char *GetPythonValueFormatString (unsigned short) { return "H"; }
+template <> const char *GetPythonValueFormatString (int) { return "i"; }
+template <> const char *GetPythonValueFormatString (unsigned int) { return "I"; }
+template <> const char *GetPythonValueFormatString (long) { return "l"; }
+template <> const char *GetPythonValueFormatString (unsigned long) { return "k"; }
+template <> const char *GetPythonValueFormatString (long long) { return "L"; }
+template <> const char *GetPythonValueFormatString (unsigned long long) { return "K"; }
+template <> const char *GetPythonValueFormatString (float t) { return "f"; }
+template <> const char *GetPythonValueFormatString (double t) { return "d"; }
+
lldb::ScriptInterpreterObjectSP
-ScriptInterpreterPython::OSPlugin_QueryForRegisterContextData (lldb::ScriptInterpreterObjectSP object,
- lldb::tid_t thread_id)
+ScriptInterpreterPython::OSPlugin_RegisterContextData (lldb::ScriptInterpreterObjectSP os_plugin_object_sp,
+ lldb::tid_t tid)
{
Locker py_lock(this,Locker::AcquireLock,Locker::FreeLock);
static char callee_name[] = "get_register_data";
- static char param_format[] = "l";
+ static char *param_format = const_cast<char *>(GetPythonValueFormatString(tid));
- if (!object)
+ if (!os_plugin_object_sp)
return lldb::ScriptInterpreterObjectSP();
- PyObject* implementor = (PyObject*)object->GetObject();
+ PyObject* implementor = (PyObject*)os_plugin_object_sp->GetObject();
if (implementor == NULL || implementor == Py_None)
return lldb::ScriptInterpreterObjectSP();
@@ -1914,7 +1935,7 @@ ScriptInterpreterPython::OSPlugin_QueryF
Py_XDECREF(pmeth);
// right now we know this function exists and is callable..
- PyObject* py_return = PyObject_CallMethod(implementor, callee_name, param_format, thread_id);
+ PyObject* py_return = PyObject_CallMethod(implementor, callee_name, param_format, tid);
// if it fails, print the error but otherwise go on
if (PyErr_Occurred())
@@ -1927,10 +1948,74 @@ ScriptInterpreterPython::OSPlugin_QueryF
}
lldb::ScriptInterpreterObjectSP
-ScriptInterpreterPython::CreateSyntheticScriptedProvider (std::string class_name,
+ScriptInterpreterPython::OSPlugin_CreateThread (lldb::ScriptInterpreterObjectSP os_plugin_object_sp,
+ lldb::tid_t tid,
+ lldb::addr_t context)
+{
+ Locker py_lock(this,Locker::AcquireLock,Locker::FreeLock);
+
+ static char callee_name[] = "create_thread";
+ std::string param_format;
+ param_format += GetPythonValueFormatString(tid);
+ param_format += GetPythonValueFormatString(context);
+
+ if (!os_plugin_object_sp)
+ return lldb::ScriptInterpreterObjectSP();
+
+ PyObject* implementor = (PyObject*)os_plugin_object_sp->GetObject();
+
+ if (implementor == NULL || implementor == Py_None)
+ return lldb::ScriptInterpreterObjectSP();
+
+ PyObject* pmeth = PyObject_GetAttrString(implementor, callee_name);
+
+ if (PyErr_Occurred())
+ {
+ PyErr_Clear();
+ }
+
+ if (pmeth == NULL || pmeth == Py_None)
+ {
+ Py_XDECREF(pmeth);
+ return lldb::ScriptInterpreterObjectSP();
+ }
+
+ if (PyCallable_Check(pmeth) == 0)
+ {
+ if (PyErr_Occurred())
+ {
+ PyErr_Clear();
+ }
+
+ Py_XDECREF(pmeth);
+ return lldb::ScriptInterpreterObjectSP();
+ }
+
+ if (PyErr_Occurred())
+ {
+ PyErr_Clear();
+ }
+
+ Py_XDECREF(pmeth);
+
+ // right now we know this function exists and is callable..
+ PyObject* py_return = PyObject_CallMethod(implementor, callee_name, ¶m_format[0], tid, context);
+
+ // if it fails, print the error but otherwise go on
+ if (PyErr_Occurred())
+ {
+ PyErr_Print();
+ PyErr_Clear();
+ }
+
+ return MakeScriptObject(py_return);
+}
+
+lldb::ScriptInterpreterObjectSP
+ScriptInterpreterPython::CreateSyntheticScriptedProvider (const char *class_name,
lldb::ValueObjectSP valobj)
{
- if (class_name.empty())
+ if (class_name == NULL || class_name[0] == '\0')
return lldb::ScriptInterpreterObjectSP();
if (!valobj.get())
@@ -2181,7 +2266,7 @@ ScriptInterpreterPython::RunEmbeddedPyth
{
ScriptInterpreterPython *script_interpreter = (ScriptInterpreterPython *) baton;
- LogSP log (lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_SCRIPT));
+ Log *log (lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_SCRIPT));
if (log)
log->Printf ("%p ScriptInterpreterPython::RunEmbeddedPythonInterpreter () thread starting...", baton);
@@ -2276,7 +2361,7 @@ ScriptInterpreterPython::PythonInputRead
return NULL;
}
-uint32_t
+size_t
ScriptInterpreterPython::CalculateNumChildren (const lldb::ScriptInterpreterObjectSP& implementor_sp)
{
if (!implementor_sp)
@@ -2591,9 +2676,9 @@ ScriptInterpreterPython::LoadScriptingMo
// if we are here, everything worked
// call __lldb_init_module(debugger,dict)
- if (!g_swig_call_module_init (basename,
- m_dictionary_name.c_str(),
- debugger_sp))
+ if (!g_swig_call_module_init (basename.c_str(),
+ m_dictionary_name.c_str(),
+ debugger_sp))
{
error.SetErrorString("calling __lldb_init_module failed");
return false;
@@ -2659,8 +2744,8 @@ ScriptInterpreterPython::RunScriptBasedC
{
Locker py_lock(this,
- Locker::AcquireLock | Locker::InitSession | Locker::InitGlobals,
- Locker::FreeLock | Locker::TearDownSession);
+ Locker::AcquireLock | Locker::InitSession,
+ Locker::FreeLock | Locker::TearDownSession);
SynchronicityHandler synch_handler(debugger_sp,
synchronicity);
@@ -2705,8 +2790,9 @@ ScriptInterpreterPython::GetDocumentatio
char* result_ptr = NULL; // Python is going to point this to valid data if ExecuteOneLineWithReturn returns successfully
if (ExecuteOneLineWithReturn (command.c_str(),
- ScriptInterpreter::eScriptReturnTypeCharStrOrNone,
- &result_ptr, ScriptInterpreter::ExecuteScriptOptions().SetEnableIO(false) /*.SetSetLLDBGlobals(false)*/))
+ ScriptInterpreter::eScriptReturnTypeCharStrOrNone,
+ &result_ptr,
+ ScriptInterpreter::ExecuteScriptOptions().SetEnableIO(false)))
{
if (result_ptr)
dest.assign(result_ptr);
@@ -2721,6 +2807,15 @@ ScriptInterpreterPython::GetDocumentatio
}
}
+std::auto_ptr<ScriptInterpreterLocker>
+ScriptInterpreterPython::AcquireInterpreterLock ()
+{
+ std::auto_ptr<ScriptInterpreterLocker> py_lock(new Locker(this,
+ Locker::AcquireLock | Locker::InitSession,
+ Locker::FreeLock | Locker::TearDownSession));
+ return py_lock;
+}
+
void
ScriptInterpreterPython::InitializeInterpreter (SWIGInitCallback python_swig_init_callback)
{
@@ -2751,7 +2846,7 @@ ScriptInterpreterPython::InitializePriva
stdin_tty_state.Save(STDIN_FILENO, false);
PyGILState_STATE gstate;
- LogSP log (lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_SCRIPT | LIBLLDB_LOG_VERBOSE));
+ Log *log (lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_SCRIPT | LIBLLDB_LOG_VERBOSE));
bool threads_already_initialized = false;
if (PyEval_ThreadsInitialized ()) {
gstate = PyGILState_Ensure ();
Modified: lldb/branches/windows/source/Makefile
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/windows/source/Makefile?rev=179679&r1=179678&r2=179679&view=diff
==============================================================================
--- lldb/branches/windows/source/Makefile (original)
+++ lldb/branches/windows/source/Makefile Wed Apr 17 03:38:48 2013
@@ -8,14 +8,30 @@
##===----------------------------------------------------------------------===##
LLDB_LEVEL := ..
-DIRS := API Breakpoint Commands Core Expression Host Interpreter Plugins Symbol Target Utility
+DIRS := API Breakpoint Commands Core DataFormatters Expression Host Interpreter Plugins Symbol Target Utility
LIBRARYNAME := lldbInitAndLog
BUILD_ARCHIVE = 1
+# Although LLVM makefiles provide $(HOST_OS), we cannot use that here because it is defined by including the $(LLDB_LEVEL)/Makefile
+# below. Instead, we use uname -s to detect the HOST_OS and generate LLDB_vers.c only on Mac. On Linux, the version number is
+# calculated in the same way as Clang's version.
+ifeq (Darwin,$(shell uname -s))
BUILT_SOURCES = LLDB_vers.c
+endif
+
SOURCES := lldb-log.cpp lldb.cpp
include $(LLDB_LEVEL)/Makefile
+ifeq ($(HOST_OS),Darwin)
LLDB_vers.c: $(PROJ_SRC_DIR)/$(LLDB_LEVEL)/scripts/generate-vers.pl $(PROJ_SRC_DIR)/$(LLDB_LEVEL)/lldb.xcodeproj/project.pbxproj
"$(PROJ_SRC_DIR)/$(LLDB_LEVEL)/scripts/generate-vers.pl" "$(PROJ_SRC_DIR)/$(LLDB_LEVEL)/lldb.xcodeproj/project.pbxproj" > LLDB_vers.c
+else
+LLDB_REVISION := $(strip \
+ $(shell $(LLVM_SRC_ROOT)/utils/GetSourceVersion $(LLVM_SRC_ROOT)/tools/lldb))
+
+LLDB_REPOSITORY := $(strip \
+ $(shell $(LLVM_SRC_ROOT)/utils/GetRepositoryPath $(LLVM_SRC_ROOT)/tools/lldb))
+
+CPP.Defines += -DLLDB_REVISION='"$(LLDB_REVISION)"' -DLLDB_REPOSITORY='"$(LLDB_REPOSITORY)"'
+endif
Modified: lldb/branches/windows/source/Plugins/ABI/MacOSX-arm/ABIMacOSX_arm.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/windows/source/Plugins/ABI/MacOSX-arm/ABIMacOSX_arm.cpp?rev=179679&r1=179678&r2=179679&view=diff
==============================================================================
--- lldb/branches/windows/source/Plugins/ABI/MacOSX-arm/ABIMacOSX_arm.cpp (original)
+++ lldb/branches/windows/source/Plugins/ABI/MacOSX-arm/ABIMacOSX_arm.cpp Wed Apr 17 03:38:48 2013
@@ -548,7 +548,7 @@ ABIMacOSX_arm::SetReturnValueObject(lldb
{
DataExtractor data;
size_t num_bytes = new_value_sp->GetData(data);
- uint32_t offset = 0;
+ lldb::offset_t offset = 0;
if (num_bytes <= 8)
{
const RegisterInfo *r0_info = reg_ctx->GetRegisterInfoByName("r0", 0);
Modified: lldb/branches/windows/source/Plugins/ABI/MacOSX-i386/ABIMacOSX_i386.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/windows/source/Plugins/ABI/MacOSX-i386/ABIMacOSX_i386.cpp?rev=179679&r1=179678&r2=179679&view=diff
==============================================================================
--- lldb/branches/windows/source/Plugins/ABI/MacOSX-i386/ABIMacOSX_i386.cpp (original)
+++ lldb/branches/windows/source/Plugins/ABI/MacOSX-i386/ABIMacOSX_i386.cpp Wed Apr 17 03:38:48 2013
@@ -722,7 +722,7 @@ ABIMacOSX_i386::SetReturnValueObject(lld
{
DataExtractor data;
size_t num_bytes = new_value_sp->GetData(data);
- uint32_t offset = 0;
+ lldb::offset_t offset = 0;
if (num_bytes <= 8)
{
const RegisterInfo *eax_info = reg_ctx->GetRegisterInfoByName("eax", 0);
Modified: lldb/branches/windows/source/Plugins/ABI/SysV-x86_64/ABISysV_x86_64.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/windows/source/Plugins/ABI/SysV-x86_64/ABISysV_x86_64.cpp?rev=179679&r1=179678&r2=179679&view=diff
==============================================================================
--- lldb/branches/windows/source/Plugins/ABI/SysV-x86_64/ABISysV_x86_64.cpp (original)
+++ lldb/branches/windows/source/Plugins/ABI/SysV-x86_64/ABISysV_x86_64.cpp Wed Apr 17 03:38:48 2013
@@ -315,7 +315,7 @@ ABISysV_x86_64::PrepareTrivialCall (Thre
addr_t *arg5_ptr,
addr_t *arg6_ptr) const
{
- LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
+ Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_EXPRESSIONS));
if (log)
log->Printf("ABISysV_x86_64::PrepareTrivialCall\n(\n thread = %p\n sp = 0x%" PRIx64 "\n func_addr = 0x%" PRIx64 "\n return_addr = 0x%" PRIx64 "\n arg1_ptr = %p (0x%" PRIx64 ")\n arg2_ptr = %p (0x%" PRIx64 ")\n arg3_ptr = %p (0x%" PRIx64 ")\n)",
@@ -470,7 +470,7 @@ ABISysV_x86_64::GetArgumentValues (Threa
// For now, assume that the types in the AST values come from the Target's
// scratch AST.
- clang::ASTContext *ast_context = thread.CalculateTarget()->GetScratchClangASTContext()->getASTContext();
+ clang::ASTContext *ast = thread.CalculateTarget()->GetScratchClangASTContext()->getASTContext();
// Extract the register context so we can read arguments from registers
@@ -522,7 +522,7 @@ ABISysV_x86_64::GetArgumentValues (Threa
if (ClangASTContext::IsIntegerType (value_type, is_signed))
{
- size_t bit_width = ClangASTType::GetClangTypeBitWidth(ast_context, value_type);
+ size_t bit_width = ClangASTType::GetClangTypeBitWidth(ast, value_type);
ReadIntegerArgument(value->GetScalar(),
bit_width,
@@ -567,8 +567,8 @@ ABISysV_x86_64::SetReturnValueObject(lld
return error;
}
- clang::ASTContext *ast_context = new_value_sp->GetClangAST();
- if (!ast_context)
+ clang::ASTContext *ast = new_value_sp->GetClangAST();
+ if (!ast)
{
error.SetErrorString ("Null clang AST for return value.");
return error;
@@ -588,7 +588,7 @@ ABISysV_x86_64::SetReturnValueObject(lld
DataExtractor data;
size_t num_bytes = new_value_sp->GetData(data);
- uint32_t offset = 0;
+ lldb::offset_t offset = 0;
if (num_bytes <= 8)
{
uint64_t raw_value = data.GetMaxU64(&offset, num_bytes);
@@ -608,7 +608,7 @@ ABISysV_x86_64::SetReturnValueObject(lld
error.SetErrorString ("We don't support returning complex values at present");
else
{
- size_t bit_width = ClangASTType::GetClangTypeBitWidth(ast_context, value_type);
+ size_t bit_width = ClangASTType::GetClangTypeBitWidth(ast, value_type);
if (bit_width <= 64)
{
const RegisterInfo *xmm0_info = reg_ctx->GetRegisterInfoByName("xmm0", 0);
@@ -645,140 +645,181 @@ ABISysV_x86_64::SetReturnValueObject(lld
ValueObjectSP
ABISysV_x86_64::GetReturnValueObjectSimple (Thread &thread,
- ClangASTType &ast_type) const
+ ClangASTType &ast_type) const
{
ValueObjectSP return_valobj_sp;
Value value;
- clang_type_t value_type = ast_type.GetOpaqueQualType();
- if (!value_type)
+ clang_type_t return_value_type = ast_type.GetOpaqueQualType();
+ if (!return_value_type)
return return_valobj_sp;
- clang::ASTContext *ast_context = ast_type.GetASTContext();
- if (!ast_context)
+ clang::ASTContext *ast = ast_type.GetASTContext();
+ if (!ast)
return return_valobj_sp;
- value.SetContext (Value::eContextTypeClangType, value_type);
+ value.SetContext (Value::eContextTypeClangType, return_value_type);
RegisterContext *reg_ctx = thread.GetRegisterContext().get();
if (!reg_ctx)
return return_valobj_sp;
- bool is_signed;
- bool is_complex;
- uint32_t count;
-
- if (ClangASTContext::IsIntegerType (value_type, is_signed))
+ const uint32_t type_flags = ClangASTContext::GetTypeInfo (return_value_type, ast, NULL);
+ if (type_flags & ClangASTContext::eTypeIsScalar)
{
- // For now, assume that the types in the AST values come from the Target's
- // scratch AST.
-
-
- // Extract the register context so we can read arguments from registers
-
- size_t bit_width = ClangASTType::GetClangTypeBitWidth(ast_context, value_type);
- uint64_t raw_value = thread.GetRegisterContext()->ReadRegisterAsUnsigned(reg_ctx->GetRegisterInfoByName("rax", 0), 0);
-
- switch (bit_width)
+ value.SetValueType(Value::eValueTypeScalar);
+
+ bool success = false;
+ if (type_flags & ClangASTContext::eTypeIsInteger)
{
- default:
- case 128:
- // Scalar can't hold 128-bit literals, so we don't handle this
- return return_valobj_sp;
- case 64:
- if (is_signed)
- value.GetScalar() = (int64_t)(raw_value);
- else
- value.GetScalar() = (uint64_t)(raw_value);
- break;
- case 32:
- if (is_signed)
- value.GetScalar() = (int32_t)(raw_value & 0xffffffff);
- else
- value.GetScalar() = (uint32_t)(raw_value & 0xffffffff);
- break;
- case 16:
- if (is_signed)
- value.GetScalar() = (int16_t)(raw_value & 0xffff);
- else
- value.GetScalar() = (uint16_t)(raw_value & 0xffff);
- break;
- case 8:
- if (is_signed)
- value.GetScalar() = (int8_t)(raw_value & 0xff);
- else
- value.GetScalar() = (uint8_t)(raw_value & 0xff);
- break;
+ // Extract the register context so we can read arguments from registers
+
+ const size_t byte_size = ClangASTType::GetClangTypeByteSize(ast, return_value_type);
+ uint64_t raw_value = thread.GetRegisterContext()->ReadRegisterAsUnsigned(reg_ctx->GetRegisterInfoByName("rax", 0), 0);
+ const bool is_signed = (type_flags & ClangASTContext::eTypeIsSigned) != 0;
+ switch (byte_size)
+ {
+ default:
+ break;
+
+ case sizeof(uint64_t):
+ if (is_signed)
+ value.GetScalar() = (int64_t)(raw_value);
+ else
+ value.GetScalar() = (uint64_t)(raw_value);
+ success = true;
+ break;
+
+ case sizeof(uint32_t):
+ if (is_signed)
+ value.GetScalar() = (int32_t)(raw_value & UINT32_MAX);
+ else
+ value.GetScalar() = (uint32_t)(raw_value & UINT32_MAX);
+ success = true;
+ break;
+
+ case sizeof(uint16_t):
+ if (is_signed)
+ value.GetScalar() = (int16_t)(raw_value & UINT16_MAX);
+ else
+ value.GetScalar() = (uint16_t)(raw_value & UINT16_MAX);
+ success = true;
+ break;
+
+ case sizeof(uint8_t):
+ if (is_signed)
+ value.GetScalar() = (int8_t)(raw_value & UINT8_MAX);
+ else
+ value.GetScalar() = (uint8_t)(raw_value & UINT8_MAX);
+ success = true;
+ break;
+ }
}
- }
- else if (ClangASTContext::IsFloatingPointType(value_type, count, is_complex))
- {
- // Don't handle complex yet.
- if (is_complex)
- return return_valobj_sp;
-
- size_t bit_width = ClangASTType::GetClangTypeBitWidth(ast_context, value_type);
- if (bit_width <= 64)
+ else if (type_flags & ClangASTContext::eTypeIsFloat)
{
- const RegisterInfo *xmm0_info = reg_ctx->GetRegisterInfoByName("xmm0", 0);
- RegisterValue xmm0_value;
- if (reg_ctx->ReadRegister (xmm0_info, xmm0_value))
+ if (type_flags & ClangASTContext::eTypeIsComplex)
{
- DataExtractor data;
- if (xmm0_value.GetData(data))
+ // Don't handle complex yet.
+ }
+ else
+ {
+ const size_t byte_size = ClangASTType::GetClangTypeByteSize(ast, return_value_type);
+ if (byte_size <= sizeof(long double))
{
- uint32_t offset = 0;
- switch (bit_width)
+ const RegisterInfo *xmm0_info = reg_ctx->GetRegisterInfoByName("xmm0", 0);
+ RegisterValue xmm0_value;
+ if (reg_ctx->ReadRegister (xmm0_info, xmm0_value))
{
- default:
- return return_valobj_sp;
- case 32:
- value.GetScalar() = (float) data.GetFloat(&offset);
- break;
- case 64:
- value.GetScalar() = (double) data.GetDouble(&offset);
- break;
+ DataExtractor data;
+ if (xmm0_value.GetData(data))
+ {
+ lldb::offset_t offset = 0;
+ if (byte_size == sizeof(float))
+ {
+ value.GetScalar() = (float) data.GetFloat(&offset);
+ success = true;
+ }
+ else if (byte_size == sizeof(double))
+ {
+ value.GetScalar() = (double) data.GetDouble(&offset);
+ success = true;
+ }
+ else if (byte_size == sizeof(long double))
+ {
+ // Don't handle long double since that can be encoded as 80 bit floats...
+ }
+ }
}
}
}
}
- else if (bit_width == 128)
- {
- // FIXME: x86_64 returns long doubles in stmm0, which is in some 80 bit long double
- // format, and so we'll have to write some code to convert that into 128 bit long doubles.
-// const RegisterInfo *st0_info = reg_ctx->GetRegisterInfoByName("stmm0", 0);
-// RegisterValue st0_value;
-// if (reg_ctx->ReadRegister (st0_info, st0_value))
-// {
-// DataExtractor data;
-// if (st0_value.GetData(data))
-// {
-// uint32_t offset = 0;
-// value.GetScalar() = (long double) data.GetLongDouble (&offset);
-// return true;
-// }
-// }
-
- return return_valobj_sp;
- }
+
+ if (success)
+ return_valobj_sp = ValueObjectConstResult::Create (thread.GetStackFrameAtIndex(0).get(),
+ ast_type.GetASTContext(),
+ value,
+ ConstString(""));
+
}
- else if (ClangASTContext::IsPointerType (value_type))
+ else if (type_flags & ClangASTContext::eTypeIsPointer)
{
unsigned rax_id = reg_ctx->GetRegisterInfoByName("rax", 0)->kinds[eRegisterKindLLDB];
value.GetScalar() = (uint64_t)thread.GetRegisterContext()->ReadRegisterAsUnsigned(rax_id, 0);
+ value.SetValueType(Value::eValueTypeScalar);
+ return_valobj_sp = ValueObjectConstResult::Create (thread.GetStackFrameAtIndex(0).get(),
+ ast_type.GetASTContext(),
+ value,
+ ConstString(""));
}
- else
+ else if (type_flags & ClangASTContext::eTypeIsVector)
{
- return return_valobj_sp;
+ const size_t byte_size = ClangASTType::GetClangTypeByteSize(ast, return_value_type);
+ if (byte_size > 0)
+ {
+
+ const RegisterInfo *altivec_reg = reg_ctx->GetRegisterInfoByName("ymm0", 0);
+ if (altivec_reg == NULL)
+ {
+ altivec_reg = reg_ctx->GetRegisterInfoByName("xmm0", 0);
+ if (altivec_reg == NULL)
+ altivec_reg = reg_ctx->GetRegisterInfoByName("mm0", 0);
+ }
+
+ if (altivec_reg)
+ {
+ if (byte_size <= altivec_reg->byte_size)
+ {
+ ProcessSP process_sp (thread.GetProcess());
+ if (process_sp)
+ {
+ std::unique_ptr<DataBufferHeap> heap_data_ap (new DataBufferHeap(byte_size, 0));
+ const ByteOrder byte_order = process_sp->GetByteOrder();
+ RegisterValue reg_value;
+ if (reg_ctx->ReadRegister(altivec_reg, reg_value))
+ {
+ Error error;
+ if (reg_value.GetAsMemoryData (altivec_reg,
+ heap_data_ap->GetBytes(),
+ heap_data_ap->GetByteSize(),
+ byte_order,
+ error))
+ {
+ DataExtractor data (DataBufferSP (heap_data_ap.release()),
+ byte_order,
+ process_sp->GetTarget().GetArchitecture().GetAddressByteSize());
+ return_valobj_sp = ValueObjectConstResult::Create (&thread,
+ ast,
+ return_value_type,
+ ConstString(""),
+ data);
+ }
+ }
+ }
+ }
+ }
+ }
}
- // If we get here, we have a valid Value, so make our ValueObject out of it:
-
- return_valobj_sp = ValueObjectConstResult::Create(
- thread.GetStackFrameAtIndex(0).get(),
- ast_type.GetASTContext(),
- value,
- ConstString(""));
return return_valobj_sp;
}
@@ -792,20 +833,20 @@ ABISysV_x86_64::GetReturnValueObjectImpl
if (return_valobj_sp)
return return_valobj_sp;
- clang_type_t ret_value_type = ast_type.GetOpaqueQualType();
- if (!ret_value_type)
+ clang_type_t return_value_type = ast_type.GetOpaqueQualType();
+ if (!return_value_type)
return return_valobj_sp;
- clang::ASTContext *ast_context = ast_type.GetASTContext();
- if (!ast_context)
+ clang::ASTContext *ast = ast_type.GetASTContext();
+ if (!ast)
return return_valobj_sp;
RegisterContextSP reg_ctx_sp = thread.GetRegisterContext();
if (!reg_ctx_sp)
return return_valobj_sp;
- size_t bit_width = ClangASTType::GetClangTypeBitWidth(ast_context, ret_value_type);
- if (ClangASTContext::IsAggregateType(ret_value_type))
+ size_t bit_width = ClangASTType::GetClangTypeBitWidth(ast, return_value_type);
+ if (ClangASTContext::IsAggregateType(return_value_type))
{
Target *target = exe_ctx.GetTargetPtr();
bool is_memory = true;
@@ -838,7 +879,7 @@ ABISysV_x86_64::GetReturnValueObjectImpl
uint32_t fp_bytes = 0; // Tracks how much of the xmm registers we've consumed so far
uint32_t integer_bytes = 0; // Tracks how much of the rax/rds registers we've consumed so far
- uint32_t num_children = ClangASTContext::GetNumFields (ast_context, ret_value_type);
+ uint32_t num_children = ClangASTContext::GetNumFields (ast, return_value_type);
// Since we are in the small struct regime, assume we are not in memory.
is_memory = false;
@@ -851,8 +892,8 @@ ABISysV_x86_64::GetReturnValueObjectImpl
bool is_complex;
uint32_t count;
- clang_type_t field_clang_type = ClangASTContext::GetFieldAtIndex (ast_context, ret_value_type, idx, name, &field_bit_offset, NULL, NULL);
- size_t field_bit_width = ClangASTType::GetClangTypeBitWidth(ast_context, field_clang_type);
+ clang_type_t field_clang_type = ClangASTContext::GetFieldAtIndex (ast, return_value_type, idx, name, &field_bit_offset, NULL, NULL);
+ size_t field_bit_width = ClangASTType::GetClangTypeBitWidth(ast, field_clang_type);
// If there are any unaligned fields, this is stored in memory.
if (field_bit_offset % field_bit_width != 0)
@@ -934,8 +975,8 @@ ABISysV_x86_64::GetReturnValueObjectImpl
else
{
uint64_t next_field_bit_offset = 0;
- clang_type_t next_field_clang_type = ClangASTContext::GetFieldAtIndex (ast_context,
- ret_value_type,
+ clang_type_t next_field_clang_type = ClangASTContext::GetFieldAtIndex (ast,
+ return_value_type,
idx + 1,
name,
&next_field_bit_offset,
@@ -960,8 +1001,8 @@ ABISysV_x86_64::GetReturnValueObjectImpl
else
{
uint64_t prev_field_bit_offset = 0;
- clang_type_t prev_field_clang_type = ClangASTContext::GetFieldAtIndex (ast_context,
- ret_value_type,
+ clang_type_t prev_field_clang_type = ClangASTContext::GetFieldAtIndex (ast,
+ return_value_type,
idx - 1,
name,
&prev_field_bit_offset,
@@ -1031,13 +1072,19 @@ ABISysV_x86_64::GetReturnValueObjectImpl
{
// The result is in our data buffer. Let's make a variable object out of it:
return_valobj_sp = ValueObjectConstResult::Create (&thread,
- ast_context,
- ret_value_type,
+ ast,
+ return_value_type,
ConstString(""),
return_ext);
}
}
+
+ // FIXME: This is just taking a guess, rax may very well no longer hold the return storage location.
+ // If we are going to do this right, when we make a new frame we should check to see if it uses a memory
+ // return, and if we are at the first instruction and if so stash away the return location. Then we would
+ // only return the memory return value if we know it is valid.
+
if (is_memory)
{
unsigned rax_id = reg_ctx_sp->GetRegisterInfoByName("rax", 0)->kinds[eRegisterKindLLDB];
Modified: lldb/branches/windows/source/Plugins/ABI/SysV-x86_64/ABISysV_x86_64.h
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/windows/source/Plugins/ABI/SysV-x86_64/ABISysV_x86_64.h?rev=179679&r1=179678&r2=179679&view=diff
==============================================================================
--- lldb/branches/windows/source/Plugins/ABI/SysV-x86_64/ABISysV_x86_64.h (original)
+++ lldb/branches/windows/source/Plugins/ABI/SysV-x86_64/ABISysV_x86_64.h Wed Apr 17 03:38:48 2013
@@ -51,7 +51,7 @@ public:
protected:
lldb::ValueObjectSP
GetReturnValueObjectSimple (lldb_private::Thread &thread,
- lldb_private::ClangASTType &ast_type) const;
+ lldb_private::ClangASTType &ast_type) const;
public:
virtual lldb::ValueObjectSP
Modified: lldb/branches/windows/source/Plugins/Disassembler/llvm/DisassemblerLLVMC.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/windows/source/Plugins/Disassembler/llvm/DisassemblerLLVMC.cpp?rev=179679&r1=179678&r2=179679&view=diff
==============================================================================
--- lldb/branches/windows/source/Plugins/Disassembler/llvm/DisassemblerLLVMC.cpp (original)
+++ lldb/branches/windows/source/Plugins/Disassembler/llvm/DisassemblerLLVMC.cpp Wed Apr 17 03:38:48 2013
@@ -10,7 +10,20 @@
#include "DisassemblerLLVMC.h"
#include "llvm-c/Disassembler.h"
+#include "llvm/MC/MCAsmInfo.h"
+#include "llvm/MC/MCContext.h"
+#include "llvm/MC/MCDisassembler.h"
+#include "llvm/MC/MCInst.h"
+#include "llvm/MC/MCInstPrinter.h"
+#include "llvm/MC/MCInstrInfo.h"
+#include "llvm/MC/MCRegisterInfo.h"
+#include "llvm/MC/MCSubtargetInfo.h"
+#include "llvm/Support/ErrorHandling.h"
+#include "llvm/Support/MemoryObject.h"
+#include "llvm/Support/TargetRegistry.h"
#include "llvm/Support/TargetSelect.h"
+#include "llvm/ADT/SmallString.h"
+
#include "lldb/Core/Address.h"
#include "lldb/Core/DataExtractor.h"
@@ -34,11 +47,11 @@ public:
InstructionLLVMC (DisassemblerLLVMC &disasm,
const lldb_private::Address &address,
AddressClass addr_class) :
- Instruction(address, addr_class),
- m_is_valid(false),
- m_disasm(disasm),
- m_disasm_sp(disasm.shared_from_this()),
- m_does_branch(eLazyBoolCalculate)
+ Instruction (address, addr_class),
+ m_disasm_sp (disasm.shared_from_this()),
+ m_does_branch (eLazyBoolCalculate),
+ m_is_valid (false),
+ m_using_file_addr (false)
{
}
@@ -47,33 +60,71 @@ public:
{
}
- static void
- PadToWidth (lldb_private::StreamString &ss,
- int new_width)
+ virtual bool
+ DoesBranch ()
{
- int old_width = ss.GetSize();
-
- if (old_width < new_width)
+ if (m_does_branch == eLazyBoolCalculate)
{
- ss.Printf("%*s", new_width - old_width, "");
+ GetDisassemblerLLVMC().Lock(this, NULL);
+ DataExtractor data;
+ if (m_opcode.GetData(data))
+ {
+ bool is_alternate_isa;
+ lldb::addr_t pc = m_address.GetFileAddress();
+
+ DisassemblerLLVMC::LLVMCDisassembler *mc_disasm_ptr = GetDisasmToUse (is_alternate_isa);
+ const uint8_t *opcode_data = data.GetDataStart();
+ const size_t opcode_data_len = data.GetByteSize();
+ llvm::MCInst inst;
+ const size_t inst_size = mc_disasm_ptr->GetMCInst (opcode_data,
+ opcode_data_len,
+ pc,
+ inst);
+ // Be conservative, if we didn't understand the instruction, say it might branch...
+ if (inst_size == 0)
+ m_does_branch = eLazyBoolYes;
+ else
+ {
+ const bool can_branch = mc_disasm_ptr->CanBranch(inst);
+ if (can_branch)
+ m_does_branch = eLazyBoolYes;
+ else
+ m_does_branch = eLazyBoolNo;
+ }
+ }
+ GetDisassemblerLLVMC().Unlock();
}
+ return m_does_branch == eLazyBoolYes;
}
-
- virtual bool
- DoesBranch () const
+
+ DisassemblerLLVMC::LLVMCDisassembler *
+ GetDisasmToUse (bool &is_alternate_isa)
{
- return m_does_branch == eLazyBoolYes;
+ is_alternate_isa = false;
+ DisassemblerLLVMC &llvm_disasm = GetDisassemblerLLVMC();
+ if (llvm_disasm.m_alternate_disasm_ap.get() != NULL)
+ {
+ const AddressClass address_class = GetAddressClass ();
+
+ if (address_class == eAddressClassCodeAlternateISA)
+ {
+ is_alternate_isa = true;
+ return llvm_disasm.m_alternate_disasm_ap.get();
+ }
+ }
+ return llvm_disasm.m_disasm_ap.get();
}
virtual size_t
Decode (const lldb_private::Disassembler &disassembler,
const lldb_private::DataExtractor &data,
- uint32_t data_offset)
+ lldb::offset_t data_offset)
{
// All we have to do is read the opcode which can be easy for some
// architetures
bool got_op = false;
- const ArchSpec &arch = m_disasm.GetArchitecture();
+ DisassemblerLLVMC &llvm_disasm = GetDisassemblerLLVMC();
+ const ArchSpec &arch = llvm_disasm.GetArchitecture();
const uint32_t min_op_byte_size = arch.GetMinimumOpcodeByteSize();
const uint32_t max_op_byte_size = arch.GetMaximumOpcodeByteSize();
@@ -113,23 +164,13 @@ public:
}
if (!got_op)
{
- ::LLVMDisasmContextRef disasm_context = m_disasm.m_disasm_context;
-
- bool is_altnernate_isa = false;
- if (m_disasm.m_alternate_disasm_context)
- {
- const AddressClass address_class = GetAddressClass ();
+ bool is_alternate_isa = false;
+ DisassemblerLLVMC::LLVMCDisassembler *mc_disasm_ptr = GetDisasmToUse (is_alternate_isa);
- if (address_class == eAddressClassCodeAlternateISA)
- {
- disasm_context = m_disasm.m_alternate_disasm_context;
- is_altnernate_isa = true;
- }
- }
const llvm::Triple::ArchType machine = arch.GetMachine();
if (machine == llvm::Triple::arm || machine == llvm::Triple::thumb)
{
- if (machine == llvm::Triple::thumb || is_altnernate_isa)
+ if (machine == llvm::Triple::thumb || is_alternate_isa)
{
uint32_t thumb_opcode = data.GetU16(&data_offset);
if ((thumb_opcode & 0xe000) != 0xe000 || ((thumb_opcode & 0x1800u) == 0))
@@ -155,20 +196,17 @@ public:
{
// The opcode isn't evenly sized, so we need to actually use the llvm
// disassembler to parse it and get the size.
- char out_string[512];
- m_disasm.Lock(this, NULL);
uint8_t *opcode_data = const_cast<uint8_t *>(data.PeekData (data_offset, 1));
- const size_t opcode_data_len = data.GetByteSize() - data_offset;
+ const size_t opcode_data_len = data.BytesLeft(data_offset);
const addr_t pc = m_address.GetFileAddress();
- const size_t inst_size = ::LLVMDisasmInstruction (disasm_context,
- opcode_data,
+ llvm::MCInst inst;
+
+ llvm_disasm.Lock(this, NULL);
+ const size_t inst_size = mc_disasm_ptr->GetMCInst(opcode_data,
opcode_data_len,
- pc, // PC value
- out_string,
- sizeof(out_string));
- // The address lookup function could have caused us to fill in our comment
- m_comment.clear();
- m_disasm.Unlock();
+ pc,
+ inst);
+ llvm_disasm.Unlock();
if (inst_size == 0)
m_opcode.Clear();
else
@@ -203,43 +241,57 @@ public:
{
char out_string[512];
- ::LLVMDisasmContextRef disasm_context;
+ DisassemblerLLVMC &llvm_disasm = GetDisassemblerLLVMC();
+
+ DisassemblerLLVMC::LLVMCDisassembler *mc_disasm_ptr;
if (address_class == eAddressClassCodeAlternateISA)
- disasm_context = m_disasm.m_alternate_disasm_context;
+ mc_disasm_ptr = llvm_disasm.m_alternate_disasm_ap.get();
else
- disasm_context = m_disasm.m_disasm_context;
+ mc_disasm_ptr = llvm_disasm.m_disasm_ap.get();
- lldb::addr_t pc = LLDB_INVALID_ADDRESS;
+ lldb::addr_t pc = m_address.GetFileAddress();
+ m_using_file_addr = true;
- if (exe_ctx)
+ const bool data_from_file = GetDisassemblerLLVMC().m_data_from_file;
+ if (!data_from_file)
{
- Target *target = exe_ctx->GetTargetPtr();
- if (target)
- pc = m_address.GetLoadAddress(target);
+ if (exe_ctx)
+ {
+ Target *target = exe_ctx->GetTargetPtr();
+ if (target)
+ {
+ const lldb::addr_t load_addr = m_address.GetLoadAddress(target);
+ if (load_addr != LLDB_INVALID_ADDRESS)
+ {
+ pc = load_addr;
+ m_using_file_addr = false;
+ }
+ }
+ }
}
- if (pc == LLDB_INVALID_ADDRESS)
- pc = m_address.GetFileAddress();
+ llvm_disasm.Lock(this, exe_ctx);
- m_disasm.Lock(this, exe_ctx);
- uint8_t *opcode_data = const_cast<uint8_t *>(data.PeekData (0, 1));
+ const uint8_t *opcode_data = data.GetDataStart();
const size_t opcode_data_len = data.GetByteSize();
- size_t inst_size = ::LLVMDisasmInstruction (disasm_context,
- opcode_data,
- opcode_data_len,
- pc,
- out_string,
- sizeof(out_string));
+ llvm::MCInst inst;
+ size_t inst_size = mc_disasm_ptr->GetMCInst (opcode_data,
+ opcode_data_len,
+ pc,
+ inst);
+
+ if (inst_size > 0)
+ mc_disasm_ptr->PrintMCInst(inst, out_string, sizeof(out_string));
- m_disasm.Unlock();
+ llvm_disasm.Unlock();
if (inst_size == 0)
{
m_comment.assign ("unknown opcode");
inst_size = m_opcode.GetByteSize();
StreamString mnemonic_strm;
- uint32_t offset = 0;
+ lldb::offset_t offset = 0;
switch (inst_size)
{
case 1:
@@ -290,17 +342,19 @@ public:
}
break;
}
- m_mnemocics.swap(mnemonic_strm.GetString());
+ m_mnemonics.swap(mnemonic_strm.GetString());
return;
}
else
{
if (m_does_branch == eLazyBoolCalculate)
{
- if (StringRepresentsBranch (out_string, strlen(out_string)))
+ const bool can_branch = mc_disasm_ptr->CanBranch(inst);
+ if (can_branch)
m_does_branch = eLazyBoolYes;
else
m_does_branch = eLazyBoolNo;
+
}
}
#if 0
@@ -317,125 +371,200 @@ public:
if (matches[1].rm_so != -1)
m_opcode_name.assign(out_string + matches[1].rm_so, matches[1].rm_eo - matches[1].rm_so);
if (matches[2].rm_so != -1)
- m_mnemocics.assign(out_string + matches[2].rm_so, matches[2].rm_eo - matches[2].rm_so);
+ m_mnemonics.assign(out_string + matches[2].rm_so, matches[2].rm_eo - matches[2].rm_so);
}
#endif
}
}
bool
- IsValid ()
+ IsValid () const
{
return m_is_valid;
}
+ bool
+ UsingFileAddress() const
+ {
+ return m_using_file_addr;
+ }
size_t
- GetByteSize ()
+ GetByteSize () const
{
return m_opcode.GetByteSize();
}
-protected:
- bool StringRepresentsBranch (const char *data, size_t size)
+ DisassemblerLLVMC &
+ GetDisassemblerLLVMC ()
{
- const char *cursor = data;
+ return *(DisassemblerLLVMC *)m_disasm_sp.get();
+ }
+protected:
+
+ DisassemblerSP m_disasm_sp; // for ownership
+ LazyBool m_does_branch;
+ bool m_is_valid;
+ bool m_using_file_addr;
+
+ static bool s_regex_compiled;
+ static ::regex_t s_regex;
+};
- bool inWhitespace = true;
+bool InstructionLLVMC::s_regex_compiled = false;
+::regex_t InstructionLLVMC::s_regex;
+
+DisassemblerLLVMC::LLVMCDisassembler::LLVMCDisassembler (const char *triple, unsigned flavor, DisassemblerLLVMC &owner):
+ m_is_valid(true)
+{
+ std::string Error;
+ const llvm::Target *curr_target = llvm::TargetRegistry::lookupTarget(triple, Error);
+ if (!curr_target)
+ {
+ m_is_valid = false;
+ return;
+ }
+
+ m_instr_info_ap.reset(curr_target->createMCInstrInfo());
+ m_reg_info_ap.reset (curr_target->createMCRegInfo(triple));
+
+ std::string features_str;
- while (inWhitespace && cursor < data + size)
+ m_subtarget_info_ap.reset(curr_target->createMCSubtargetInfo(triple, "",
+ features_str));
+
+ m_asm_info_ap.reset(curr_target->createMCAsmInfo(triple));
+
+ if (m_instr_info_ap.get() == NULL || m_reg_info_ap.get() == NULL || m_subtarget_info_ap.get() == NULL || m_asm_info_ap.get() == NULL)
+ {
+ m_is_valid = false;
+ return;
+ }
+
+ m_context_ap.reset(new llvm::MCContext(*m_asm_info_ap.get(), *(m_reg_info_ap.get()), 0));
+
+ m_disasm_ap.reset(curr_target->createMCDisassembler(*m_subtarget_info_ap.get()));
+ if (m_disasm_ap.get())
+ {
+ m_disasm_ap->setupForSymbolicDisassembly(NULL,
+ DisassemblerLLVMC::SymbolLookupCallback,
+ (void *) &owner,
+ m_context_ap.get());
+
+ unsigned asm_printer_variant;
+ if (flavor == ~0U)
+ asm_printer_variant = m_asm_info_ap->getAssemblerDialect();
+ else
{
- switch (*cursor)
- {
- default:
- inWhitespace = false;
- break;
- case ' ':
- break;
- case '\t':
- break;
- }
-
- if (inWhitespace)
- ++cursor;
+ asm_printer_variant = flavor;
}
- if (cursor >= data + size)
- return false;
-
- llvm::Triple::ArchType arch = m_disasm.GetArchitecture().GetMachine();
-
- switch (arch)
+ m_instr_printer_ap.reset(curr_target->createMCInstPrinter(asm_printer_variant,
+ *m_asm_info_ap.get(),
+ *m_instr_info_ap.get(),
+ *m_reg_info_ap.get(),
+ *m_subtarget_info_ap.get()));
+ if (m_instr_printer_ap.get() == NULL)
{
- default:
- return false;
- case llvm::Triple::x86:
- case llvm::Triple::x86_64:
- switch (cursor[0])
- {
- default:
- return false;
- case 'j':
- return true;
- case 'c':
- if (cursor[1] == 'a' &&
- cursor[2] == 'l' &&
- cursor[3] == 'l')
- return true;
- else
- return false;
- }
- case llvm::Triple::arm:
- case llvm::Triple::thumb:
- switch (cursor[0])
- {
- default:
- return false;
- case 'b':
- {
- switch (cursor[1])
- {
- default:
- return true;
- case 'f':
- case 'i':
- case 'k':
- return false;
- }
- }
- case 'c':
- {
- switch (cursor[1])
- {
- default:
- return false;
- case 'b':
- return true;
- }
- }
- }
+ m_disasm_ap.reset();
+ m_is_valid = false;
}
-
- return false;
}
+ else
+ m_is_valid = false;
+}
+
+namespace {
+ // This is the memory object we use in GetInstruction.
+ class LLDBDisasmMemoryObject : public llvm::MemoryObject {
+ const uint8_t *m_bytes;
+ uint64_t m_size;
+ uint64_t m_base_PC;
+ public:
+ LLDBDisasmMemoryObject(const uint8_t *bytes, uint64_t size, uint64_t basePC) :
+ m_bytes(bytes), m_size(size), m_base_PC(basePC) {}
+
+ uint64_t getBase() const { return m_base_PC; }
+ uint64_t getExtent() const { return m_size; }
+
+ int readByte(uint64_t addr, uint8_t *byte) const {
+ if (addr - m_base_PC >= m_size)
+ return -1;
+ *byte = m_bytes[addr - m_base_PC];
+ return 0;
+ }
+ };
+} // End Anonymous Namespace
+
+uint64_t
+DisassemblerLLVMC::LLVMCDisassembler::GetMCInst (const uint8_t *opcode_data,
+ size_t opcode_data_len,
+ lldb::addr_t pc,
+ llvm::MCInst &mc_inst)
+{
+ LLDBDisasmMemoryObject memory_object (opcode_data, opcode_data_len, pc);
+ llvm::MCDisassembler::DecodeStatus status;
+
+ uint64_t new_inst_size;
+ status = m_disasm_ap->getInstruction(mc_inst,
+ new_inst_size,
+ memory_object,
+ pc,
+ llvm::nulls(),
+ llvm::nulls());
+ if (status == llvm::MCDisassembler::Success)
+ return new_inst_size;
+ else
+ return 0;
+}
+
+uint64_t
+DisassemblerLLVMC::LLVMCDisassembler::PrintMCInst (llvm::MCInst &mc_inst,
+ char *dst,
+ size_t dst_len)
+{
+ llvm::StringRef unused_annotations;
+ llvm::SmallString<64> inst_string;
+ llvm::raw_svector_ostream inst_stream(inst_string);
+ m_instr_printer_ap->printInst (&mc_inst, inst_stream, unused_annotations);
+ inst_stream.flush();
+ const size_t output_size = std::min(dst_len - 1, inst_string.size());
+ std::memcpy(dst, inst_string.data(), output_size);
+ dst[output_size] = '\0';
- bool m_is_valid;
- DisassemblerLLVMC &m_disasm;
- DisassemblerSP m_disasm_sp; // for ownership
- LazyBool m_does_branch;
-
- static bool s_regex_compiled;
- static lldb::RegularExpressionSP s_regex;
-};
+ return output_size;
+}
-bool InstructionLLVMC::s_regex_compiled = false;
-lldb::RegularExpressionSP InstructionLLVMC::s_regex;
+bool
+DisassemblerLLVMC::LLVMCDisassembler::CanBranch (llvm::MCInst &mc_inst)
+{
+ return m_instr_info_ap->get(mc_inst.getOpcode()).mayAffectControlFlow(mc_inst, *m_reg_info_ap.get());
+}
+
+bool
+DisassemblerLLVMC::FlavorValidForArchSpec (const lldb_private::ArchSpec &arch, const char *flavor)
+{
+ llvm::Triple triple = arch.GetTriple();
+ if (flavor == NULL || strcmp (flavor, "default") == 0)
+ return true;
+
+ if (triple.getArch() == llvm::Triple::x86 || triple.getArch() == llvm::Triple::x86_64)
+ {
+ if (strcmp (flavor, "intel") == 0 || strcmp (flavor, "att") == 0)
+ return true;
+ else
+ return false;
+ }
+ else
+ return false;
+}
+
Disassembler *
-DisassemblerLLVMC::CreateInstance (const ArchSpec &arch)
+DisassemblerLLVMC::CreateInstance (const ArchSpec &arch, const char *flavor)
{
if (arch.GetTriple().getArch() != llvm::Triple::UnknownArch)
{
- std::auto_ptr<DisassemblerLLVMC> disasm_ap (new DisassemblerLLVMC(arch));
+ std::auto_ptr<DisassemblerLLVMC> disasm_ap (new DisassemblerLLVMC(arch, flavor));
if (disasm_ap.get() && disasm_ap->IsValid())
return disasm_ap.release();
@@ -443,18 +572,42 @@ DisassemblerLLVMC::CreateInstance (const
return NULL;
}
-DisassemblerLLVMC::DisassemblerLLVMC (const ArchSpec &arch) :
- Disassembler(arch),
+DisassemblerLLVMC::DisassemblerLLVMC (const ArchSpec &arch, const char *flavor_string) :
+ Disassembler(arch, flavor_string),
m_exe_ctx (NULL),
m_inst (NULL),
- m_disasm_context (NULL),
- m_alternate_disasm_context (NULL)
+ m_data_from_file (false)
{
- m_disasm_context = ::LLVMCreateDisasm(arch.GetTriple().getTriple().c_str(),
- (void*)this,
- /*TagType=*/1,
- NULL,
- DisassemblerLLVMC::SymbolLookupCallback);
+ if (!FlavorValidForArchSpec (arch, m_flavor.c_str()))
+ {
+ m_flavor.assign("default");
+ }
+
+ const char *triple = arch.GetTriple().getTriple().c_str();
+ unsigned flavor = ~0U;
+
+ // So far the only supported flavor is "intel" on x86. The base class will set this
+ // correctly coming in.
+ if (arch.GetTriple().getArch() == llvm::Triple::x86
+ || arch.GetTriple().getArch() == llvm::Triple::x86_64)
+ {
+ if (m_flavor == "intel")
+ {
+ flavor = 1;
+ }
+ else if (m_flavor == "att")
+ {
+ flavor = 0;
+ }
+ }
+
+ m_disasm_ap.reset (new LLVMCDisassembler(triple, flavor, *this));
+ if (!m_disasm_ap->IsValid())
+ {
+ // We use m_disasm_ap.get() to tell whether we are valid or not, so if this isn't good for some reason,
+ // we reset it, and then we won't be valid and FindPlugin will fail and we won't get used.
+ m_disasm_ap.reset();
+ }
if (arch.GetTriple().getArch() == llvm::Triple::arm)
{
@@ -462,34 +615,26 @@ DisassemblerLLVMC::DisassemblerLLVMC (co
thumb_arch.GetTriple().setArchName(llvm::StringRef("thumbv7"));
std::string thumb_triple(thumb_arch.GetTriple().getTriple());
- m_alternate_disasm_context = ::LLVMCreateDisasm(thumb_triple.c_str(),
- (void*)this,
- /*TagType=*/1,
- NULL,
- DisassemblerLLVMC::SymbolLookupCallback);
+ m_alternate_disasm_ap.reset(new LLVMCDisassembler(thumb_triple.c_str(), flavor, *this));
+ if (!m_alternate_disasm_ap->IsValid())
+ {
+ m_disasm_ap.reset();
+ m_alternate_disasm_ap.reset();
+ }
}
}
DisassemblerLLVMC::~DisassemblerLLVMC()
{
- if (m_disasm_context)
- {
- ::LLVMDisasmDispose(m_disasm_context);
- m_disasm_context = NULL;
- }
- if (m_alternate_disasm_context)
- {
- ::LLVMDisasmDispose(m_alternate_disasm_context);
- m_alternate_disasm_context = NULL;
- }
}
size_t
DisassemblerLLVMC::DecodeInstructions (const Address &base_addr,
const DataExtractor& data,
- uint32_t data_offset,
- uint32_t num_instructions,
- bool append)
+ lldb::offset_t data_offset,
+ size_t num_instructions,
+ bool append,
+ bool data_from_file)
{
if (!append)
m_instruction_list.Clear();
@@ -497,6 +642,7 @@ DisassemblerLLVMC::DecodeInstructions (c
if (!IsValid())
return 0;
+ m_data_from_file = data_from_file;
uint32_t data_cursor = data_offset;
const size_t data_byte_size = data.GetByteSize();
uint32_t instructions_parsed = 0;
@@ -507,7 +653,7 @@ DisassemblerLLVMC::DecodeInstructions (c
AddressClass address_class = eAddressClassCode;
- if (m_alternate_disasm_context)
+ if (m_alternate_disasm_ap.get() != NULL)
address_class = inst_addr.GetAddressClass ();
InstructionSP inst_sp(new InstructionLLVMC(*this,
@@ -616,36 +762,33 @@ const char *DisassemblerLLVMC::SymbolLoo
if (m_exe_ctx && m_inst)
{
//std::string remove_this_prior_to_checkin;
- Address reference_address;
-
Target *target = m_exe_ctx ? m_exe_ctx->GetTargetPtr() : NULL;
-
- if (target && !target->GetSectionLoadList().IsEmpty())
- target->GetSectionLoadList().ResolveLoadAddress(value, reference_address);
- else
+ Address value_so_addr;
+ if (m_inst->UsingFileAddress())
{
ModuleSP module_sp(m_inst->GetAddress().GetModule());
if (module_sp)
- module_sp->ResolveFileAddress(value, reference_address);
+ module_sp->ResolveFileAddress(value, value_so_addr);
}
-
- if (reference_address.IsValid() && reference_address.GetSection())
+ else if (target && !target->GetSectionLoadList().IsEmpty())
+ {
+ target->GetSectionLoadList().ResolveLoadAddress(value, value_so_addr);
+ }
+
+ if (value_so_addr.IsValid() && value_so_addr.GetSection())
{
StreamString ss;
- reference_address.Dump (&ss,
- target,
- Address::DumpStyleResolvedDescriptionNoModule,
- Address::DumpStyleSectionNameOffset);
+ value_so_addr.Dump (&ss,
+ target,
+ Address::DumpStyleResolvedDescriptionNoModule,
+ Address::DumpStyleSectionNameOffset);
if (!ss.GetString().empty())
{
- //remove_this_prior_to_checkin = ss.GetString();
- //if (*type_ptr)
m_inst->AppendComment(ss.GetString());
}
}
- //printf ("DisassemblerLLVMC::SymbolLookup (value=0x%16.16" PRIx64 ", type=%" PRIu64 ", pc=0x%16.16" PRIx64 ", name=\"%s\") m_exe_ctx=%p, m_inst=%p\n", value, *type_ptr, pc, remove_this_prior_to_checkin.c_str(), m_exe_ctx, m_inst);
}
}
Modified: lldb/branches/windows/source/Plugins/Disassembler/llvm/DisassemblerLLVMC.h
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/windows/source/Plugins/Disassembler/llvm/DisassemblerLLVMC.h?rev=179679&r1=179678&r2=179679&view=diff
==============================================================================
--- lldb/branches/windows/source/Plugins/Disassembler/llvm/DisassemblerLLVMC.h (original)
+++ lldb/branches/windows/source/Plugins/Disassembler/llvm/DisassemblerLLVMC.h Wed Apr 17 03:38:48 2013
@@ -10,9 +10,23 @@
#ifndef liblldb_DisassemblerLLVMC_h_
#define liblldb_DisassemblerLLVMC_h_
+#include <string>
#include "llvm-c/Disassembler.h"
+// Opaque references to C++ Objects in LLVM's MC.
+namespace llvm
+{
+ class MCContext;
+ class MCInst;
+ class MCInstrInfo;
+ class MCRegisterInfo;
+ class MCDisassembler;
+ class MCInstPrinter;
+ class MCAsmInfo;
+ class MCSubtargetInfo;
+}
+
#include "lldb/Core/Address.h"
#include "lldb/Core/Disassembler.h"
#include "lldb/Core/PluginManager.h"
@@ -22,6 +36,34 @@ class InstructionLLVMC;
class DisassemblerLLVMC : public lldb_private::Disassembler
{
+ // Since we need to make two actual MC Disassemblers for ARM (ARM & THUMB), and there's a bit of goo to set up and own
+ // in the MC disassembler world, I added this class to manage the actual disassemblers.
+ class LLVMCDisassembler
+ {
+ public:
+ LLVMCDisassembler (const char *triple, unsigned flavor, DisassemblerLLVMC &owner);
+
+ ~LLVMCDisassembler() {};
+
+ uint64_t GetMCInst (const uint8_t *opcode_data, size_t opcode_data_len, lldb::addr_t pc, llvm::MCInst &mc_inst);
+ uint64_t PrintMCInst (llvm::MCInst &mc_inst, char *output_buffer, size_t out_buffer_len);
+ bool CanBranch (llvm::MCInst &mc_inst);
+ bool IsValid()
+ {
+ return m_is_valid;
+ }
+
+ private:
+ bool m_is_valid;
+ std::auto_ptr<llvm::MCContext> m_context_ap;
+ std::auto_ptr<llvm::MCAsmInfo> m_asm_info_ap;
+ std::auto_ptr<llvm::MCSubtargetInfo> m_subtarget_info_ap;
+ std::auto_ptr<llvm::MCInstrInfo> m_instr_info_ap;
+ std::auto_ptr<llvm::MCRegisterInfo> m_reg_info_ap;
+ std::auto_ptr<llvm::MCInstPrinter> m_instr_printer_ap;
+ std::auto_ptr<llvm::MCDisassembler> m_disasm_ap;
+ };
+
public:
//------------------------------------------------------------------
// Static Functions
@@ -39,20 +81,20 @@ public:
GetPluginDescriptionStatic();
static lldb_private::Disassembler *
- CreateInstance(const lldb_private::ArchSpec &arch);
-
-
- DisassemblerLLVMC(const lldb_private::ArchSpec &arch);
+ CreateInstance(const lldb_private::ArchSpec &arch, const char *flavor);
+
+ DisassemblerLLVMC(const lldb_private::ArchSpec &arch, const char *flavor /* = NULL */);
virtual
~DisassemblerLLVMC();
- size_t
+ virtual size_t
DecodeInstructions (const lldb_private::Address &base_addr,
const lldb_private::DataExtractor& data,
- uint32_t data_offset,
- uint32_t num_instructions,
- bool append);
+ lldb::offset_t data_offset,
+ size_t num_instructions,
+ bool append,
+ bool data_from_file);
//------------------------------------------------------------------
// PluginInterface protocol
@@ -69,10 +111,13 @@ public:
protected:
friend class InstructionLLVMC;
+ virtual bool
+ FlavorValidForArchSpec (const lldb_private::ArchSpec &arch, const char *flavor);
+
bool
IsValid()
{
- return (m_disasm_context != NULL);
+ return (m_disasm_ap.get() != NULL && m_disasm_ap->IsValid());
}
int OpInfo(uint64_t PC,
@@ -117,8 +162,10 @@ protected:
const lldb_private::ExecutionContext *m_exe_ctx;
InstructionLLVMC *m_inst;
lldb_private::Mutex m_mutex;
- ::LLVMDisasmContextRef m_disasm_context;
- ::LLVMDisasmContextRef m_alternate_disasm_context;
+ bool m_data_from_file;
+
+ std::auto_ptr<LLVMCDisassembler> m_disasm_ap;
+ std::auto_ptr<LLVMCDisassembler> m_alternate_disasm_ap;
};
#endif // liblldb_DisassemblerLLVM_h_
Modified: lldb/branches/windows/source/Plugins/DynamicLoader/Darwin-Kernel/DynamicLoaderDarwinKernel.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/windows/source/Plugins/DynamicLoader/Darwin-Kernel/DynamicLoaderDarwinKernel.cpp?rev=179679&r1=179678&r2=179679&view=diff
==============================================================================
--- lldb/branches/windows/source/Plugins/DynamicLoader/Darwin-Kernel/DynamicLoaderDarwinKernel.cpp (original)
+++ lldb/branches/windows/source/Plugins/DynamicLoader/Darwin-Kernel/DynamicLoaderDarwinKernel.cpp Wed Apr 17 03:38:48 2013
@@ -41,15 +41,39 @@
using namespace lldb;
using namespace lldb_private;
+// Progressively greater amounts of scanning we will allow
+// For some targets very early in startup, we can't do any random reads of memory or we can crash the device
+// so a setting is needed that can completely disable the KASLR scans.
+
+enum KASLRScanType
+{
+ eKASLRScanNone = 0, // No reading into the inferior at all
+ eKASLRScanLowgloAddresses, // Check one word of memory for a possible kernel addr, then see if a kernel is there
+ eKASLRScanNearPC, // Scan backwards from the current $pc looking for kernel; checking at 96 locations total
+ eKASLRScanExhaustiveScan // Scan through the entire possible kernel address range looking for a kernel
+};
+
+OptionEnumValueElement
+g_kaslr_kernel_scan_enum_values[] =
+{
+ { eKASLRScanNone, "none", "Do not read memory looking for a Darwin kernel when attaching." },
+ { eKASLRScanLowgloAddresses, "basic", "Check for the Darwin kernel's load addr in the lowglo page (boot-args=debug) only." },
+ { eKASLRScanNearPC, "fast-scan", "Scan near the pc value on attach to find the Darwin kernel's load address."},
+ { eKASLRScanExhaustiveScan, "exhaustive-scan", "Scan through the entire potential address range of Darwin kernel (only on 32-bit targets)."},
+ { 0, NULL, NULL }
+};
+
static PropertyDefinition
g_properties[] =
{
{ "load-kexts" , OptionValue::eTypeBoolean, true, true, NULL, NULL, "Automatically loads kext images when attaching to a kernel." },
+ { "scan-type", OptionValue::eTypeEnum, true, eKASLRScanNearPC, NULL, g_kaslr_kernel_scan_enum_values, "Control how many reads lldb will make while searching for a Darwin kernel on attach." },
{ NULL , OptionValue::eTypeInvalid, false, 0 , NULL, NULL, NULL }
};
enum {
- ePropertyLoadKexts
+ ePropertyLoadKexts,
+ ePropertyScanType
};
class DynamicLoaderDarwinKernelProperties : public Properties
@@ -74,14 +98,22 @@ public:
~DynamicLoaderDarwinKernelProperties()
{
}
-
+
bool
GetLoadKexts() const
{
const uint32_t idx = ePropertyLoadKexts;
return m_collection_sp->GetPropertyAtIndexAsBoolean (NULL, idx, g_properties[idx].default_uint_value != 0);
}
-
+
+ KASLRScanType
+ GetScanType() const
+ {
+ const uint32_t idx = ePropertyScanType;
+ return (KASLRScanType) m_collection_sp->GetPropertyAtIndexAsEnumeration (NULL, idx, g_properties[idx].default_uint_value);
+ }
+
+
};
typedef STD_SHARED_PTR(DynamicLoaderDarwinKernelProperties) DynamicLoaderDarwinKernelPropertiesSP;
@@ -103,57 +135,336 @@ GetGlobalProperties()
DynamicLoader *
DynamicLoaderDarwinKernel::CreateInstance (Process* process, bool force)
{
- bool create = force;
- if (!create)
+ if (!force)
{
+ // If the user provided an executable binary and it is not a kernel,
+ // this plugin should not create an instance.
Module* exe_module = process->GetTarget().GetExecutableModulePointer();
if (exe_module)
{
ObjectFile *object_file = exe_module->GetObjectFile();
if (object_file)
{
- create = (object_file->GetStrata() == ObjectFile::eStrataKernel);
+ if (object_file->GetStrata() != ObjectFile::eStrataKernel)
+ {
+ return NULL;
+ }
}
}
-
- if (create)
+
+ // If the target's architecture does not look like an Apple environment,
+ // this plugin should not create an instance.
+ const llvm::Triple &triple_ref = process->GetTarget().GetArchitecture().GetTriple();
+ switch (triple_ref.getOS())
{
- const llvm::Triple &triple_ref = process->GetTarget().GetArchitecture().GetTriple();
- switch (triple_ref.getOS())
- {
- case llvm::Triple::Darwin:
- case llvm::Triple::MacOSX:
- case llvm::Triple::IOS:
- create = triple_ref.getVendor() == llvm::Triple::Apple;
- break;
- default:
- create = false;
- break;
- }
+ case llvm::Triple::Darwin:
+ case llvm::Triple::MacOSX:
+ case llvm::Triple::IOS:
+ if (triple_ref.getVendor() != llvm::Triple::Apple)
+ {
+ return NULL;
+ }
+ break;
+ // If we have triple like armv7-unknown-unknown, we should try looking for a Darwin kernel.
+ case llvm::Triple::UnknownOS:
+ break;
+ default:
+ return NULL;
+ break;
}
}
-
- if (create)
+
+ // At this point if there is an ExecutableModule, it is a kernel and the Target is some variant of an Apple system.
+ // If the Process hasn't provided the kernel load address, we need to look around in memory to find it.
+
+ addr_t kernel_load_address = SearchForDarwinKernel (process);
+ if (kernel_load_address != LLDB_INVALID_ADDRESS)
{
process->SetCanJIT(false);
- return new DynamicLoaderDarwinKernel (process);
+ return new DynamicLoaderDarwinKernel (process, kernel_load_address);
}
return NULL;
}
+lldb::addr_t
+DynamicLoaderDarwinKernel::SearchForDarwinKernel (Process *process)
+{
+ addr_t kernel_load_address = process->GetImageInfoAddress();
+ if (kernel_load_address == LLDB_INVALID_ADDRESS)
+ {
+ kernel_load_address = SearchForKernelAtSameLoadAddr (process);
+ if (kernel_load_address == LLDB_INVALID_ADDRESS)
+ {
+ kernel_load_address = SearchForKernelWithDebugHints (process);
+ if (kernel_load_address == LLDB_INVALID_ADDRESS)
+ {
+ kernel_load_address = SearchForKernelNearPC (process);
+ if (kernel_load_address == LLDB_INVALID_ADDRESS)
+ {
+ kernel_load_address = SearchForKernelViaExhaustiveSearch (process);
+ }
+ }
+ }
+ }
+ return kernel_load_address;
+}
+
+//----------------------------------------------------------------------
+// Check if the kernel binary is loaded in memory without a slide.
+// First verify that the ExecutableModule is a kernel before we proceed.
+// Returns the address of the kernel if one was found, else LLDB_INVALID_ADDRESS.
+//----------------------------------------------------------------------
+lldb::addr_t
+DynamicLoaderDarwinKernel::SearchForKernelAtSameLoadAddr (Process *process)
+{
+ Module *exe_module = process->GetTarget().GetExecutableModulePointer();
+ if (exe_module == NULL)
+ return LLDB_INVALID_ADDRESS;
+
+ ObjectFile *exe_objfile = exe_module->GetObjectFile();
+ if (exe_objfile == NULL)
+ return LLDB_INVALID_ADDRESS;
+
+ if (exe_objfile->GetType() != ObjectFile::eTypeExecutable || exe_objfile->GetStrata() != ObjectFile::eStrataKernel)
+ return LLDB_INVALID_ADDRESS;
+
+ if (!exe_objfile->GetHeaderAddress().IsValid())
+ return LLDB_INVALID_ADDRESS;
+
+ if (CheckForKernelImageAtAddress (exe_objfile->GetHeaderAddress().GetFileAddress(), process) == exe_module->GetUUID())
+ return exe_objfile->GetHeaderAddress().GetFileAddress();
+
+ return LLDB_INVALID_ADDRESS;
+}
+
+//----------------------------------------------------------------------
+// If the debug flag is included in the boot-args nvram setting, the kernel's load address
+// will be noted in the lowglo page at a fixed address
+// Returns the address of the kernel if one was found, else LLDB_INVALID_ADDRESS.
+//----------------------------------------------------------------------
+lldb::addr_t
+DynamicLoaderDarwinKernel::SearchForKernelWithDebugHints (Process *process)
+{
+ if (GetGlobalProperties()->GetScanType() == eKASLRScanNone)
+ return LLDB_INVALID_ADDRESS;
+
+ Error read_err;
+ addr_t addr = LLDB_INVALID_ADDRESS;
+ if (process->GetTarget().GetArchitecture().GetAddressByteSize() == 8)
+ {
+ addr = process->ReadUnsignedIntegerFromMemory (0xffffff8000002010ULL, 8, LLDB_INVALID_ADDRESS, read_err);
+ }
+ else
+ {
+ addr = process->ReadUnsignedIntegerFromMemory (0xffff0110, 4, LLDB_INVALID_ADDRESS, read_err);
+ }
+
+ if (addr == 0)
+ addr = LLDB_INVALID_ADDRESS;
+
+ if (addr != LLDB_INVALID_ADDRESS)
+ {
+ if (CheckForKernelImageAtAddress (addr, process).IsValid())
+ return addr;
+ }
+
+ return LLDB_INVALID_ADDRESS;
+}
+
+//----------------------------------------------------------------------
+// If the kernel is currently executing when lldb attaches, and we don't have
+// a better way of finding the kernel's load address, try searching backwards
+// from the current pc value looking for the kernel's Mach header in memory.
+// Returns the address of the kernel if one was found, else LLDB_INVALID_ADDRESS.
+//----------------------------------------------------------------------
+lldb::addr_t
+DynamicLoaderDarwinKernel::SearchForKernelNearPC (Process *process)
+{
+ if (GetGlobalProperties()->GetScanType() == eKASLRScanNone
+ || GetGlobalProperties()->GetScanType() == eKASLRScanLowgloAddresses)
+ {
+ return LLDB_INVALID_ADDRESS;
+ }
+
+ ThreadSP thread = process->GetThreadList().GetSelectedThread ();
+ if (thread.get() == NULL)
+ return LLDB_INVALID_ADDRESS;
+ addr_t pc = thread->GetRegisterContext ()->GetPC(LLDB_INVALID_ADDRESS);
+
+ if (pc == LLDB_INVALID_ADDRESS)
+ return LLDB_INVALID_ADDRESS;
+
+ addr_t kernel_range_low, kernel_range_high;
+ if (process->GetTarget().GetArchitecture().GetAddressByteSize() == 8)
+ {
+ kernel_range_low = 1ULL << 63;
+ kernel_range_high = UINT64_MAX;
+ }
+ else
+ {
+ kernel_range_low = 1ULL << 31;
+ kernel_range_high = UINT32_MAX;
+ }
+
+ // Outside the normal kernel address range, this is probably userland code running right now
+ if (pc < kernel_range_low)
+ LLDB_INVALID_ADDRESS;
+
+ // The kernel will load at at one megabyte boundary (0x100000), or at that boundary plus
+ // an offset of one page (0x1000) or two, depending on the device.
+
+ // Round the current pc down to the nearest one megabyte boundary - the place where we will start searching.
+ addr_t addr = pc & ~0xfffff;
+
+ int i = 0;
+ while (i < 32 && pc >= kernel_range_low)
+ {
+ if (CheckForKernelImageAtAddress (addr, process).IsValid())
+ return addr;
+ if (CheckForKernelImageAtAddress (addr + 0x1000, process).IsValid())
+ return addr + 0x1000;
+ if (CheckForKernelImageAtAddress (addr + 0x2000, process).IsValid())
+ return addr + 0x2000;
+ i++;
+ addr -= 0x100000;
+ }
+
+ return LLDB_INVALID_ADDRESS;
+}
+
+//----------------------------------------------------------------------
+// Scan through the valid address range for a kernel binary.
+// This is uselessly slow in 64-bit environments so we don't even try it.
+// This scan is not enabled by default even for 32-bit targets.
+// Returns the address of the kernel if one was found, else LLDB_INVALID_ADDRESS.
+//----------------------------------------------------------------------
+lldb::addr_t
+DynamicLoaderDarwinKernel::SearchForKernelViaExhaustiveSearch (Process *process)
+{
+ if (GetGlobalProperties()->GetScanType() != eKASLRScanExhaustiveScan)
+ {
+ return LLDB_INVALID_ADDRESS;
+ }
+
+ addr_t kernel_range_low, kernel_range_high;
+ if (process->GetTarget().GetArchitecture().GetAddressByteSize() == 8)
+ {
+ kernel_range_low = 1ULL << 63;
+ kernel_range_high = UINT64_MAX;
+ }
+ else
+ {
+ kernel_range_low = 1ULL << 31;
+ kernel_range_high = UINT32_MAX;
+ }
+
+ // Stepping through memory at one-megabyte resolution looking for a kernel
+ // rarely works (fast enough) with a 64-bit address space -- for now, let's
+ // not even bother. We may be attaching to something which *isn't* a kernel
+ // and we don't want to spin for minutes on-end looking for a kernel.
+ if (process->GetTarget().GetArchitecture().GetAddressByteSize() == 8)
+ return LLDB_INVALID_ADDRESS;
+
+ addr_t addr = kernel_range_low;
+
+ while (addr >= kernel_range_low && addr < kernel_range_high)
+ {
+ if (CheckForKernelImageAtAddress (addr, process).IsValid())
+ return addr;
+ if (CheckForKernelImageAtAddress (addr + 0x1000, process).IsValid())
+ return addr + 0x1000;
+ if (CheckForKernelImageAtAddress (addr + 0x2000, process).IsValid())
+ return addr + 0x2000;
+ addr += 0x100000;
+ }
+ return LLDB_INVALID_ADDRESS;
+}
+
+//----------------------------------------------------------------------
+// Given an address in memory, look to see if there is a kernel image at that
+// address.
+// Returns a UUID; if a kernel was not found at that address, UUID.IsValid() will be false.
+//----------------------------------------------------------------------
+lldb_private::UUID
+DynamicLoaderDarwinKernel::CheckForKernelImageAtAddress (lldb::addr_t addr, Process *process)
+{
+ if (addr == LLDB_INVALID_ADDRESS)
+ return UUID();
+
+ // First try a quick test -- read the first 4 bytes and see if there is a valid Mach-O magic field there
+ // (the first field of the mach_header/mach_header_64 struct).
+
+ Error read_error;
+ uint64_t result = process->ReadUnsignedIntegerFromMemory (addr, 4, LLDB_INVALID_ADDRESS, read_error);
+ if (result != llvm::MachO::HeaderMagic64
+ && result != llvm::MachO::HeaderMagic32
+ && result != llvm::MachO::HeaderMagic32Swapped
+ && result != llvm::MachO::HeaderMagic64Swapped)
+ {
+ return UUID();
+ }
+
+ // Read the mach header and see whether it looks like a kernel
+ llvm::MachO::mach_header header;
+ if (process->DoReadMemory (addr, &header, sizeof(header), read_error) != sizeof(header))
+ return UUID();
+
+ if (header.magic == llvm::MachO::HeaderMagic32Swapped ||
+ header.magic == llvm::MachO::HeaderMagic64Swapped)
+ {
+ header.magic = llvm::ByteSwap_32(header.magic);
+ header.cputype = llvm::ByteSwap_32(header.cputype);
+ header.cpusubtype = llvm::ByteSwap_32(header.cpusubtype);
+ header.filetype = llvm::ByteSwap_32(header.filetype);
+ header.ncmds = llvm::ByteSwap_32(header.ncmds);
+ header.sizeofcmds = llvm::ByteSwap_32(header.sizeofcmds);
+ header.flags = llvm::ByteSwap_32(header.flags);
+ }
+
+ // A kernel is an executable which does not have the dynamic link object flag set.
+ if (header.filetype == llvm::MachO::HeaderFileTypeExecutable
+ && (header.flags & llvm::MachO::HeaderFlagBitIsDynamicLinkObject) == 0)
+ {
+ // Create a full module to get the UUID
+ ModuleSP memory_module_sp = process->ReadModuleFromMemory (FileSpec ("temp_mach_kernel", false), addr);
+ if (!memory_module_sp.get())
+ return UUID();
+
+ ObjectFile *exe_objfile = memory_module_sp->GetObjectFile();
+ if (exe_objfile == NULL)
+ return UUID();
+
+ if (exe_objfile->GetType() == ObjectFile::eTypeExecutable && exe_objfile->GetStrata() == ObjectFile::eStrataKernel)
+ {
+ return memory_module_sp->GetUUID();
+ }
+ }
+
+ return UUID();
+}
+
//----------------------------------------------------------------------
// Constructor
//----------------------------------------------------------------------
-DynamicLoaderDarwinKernel::DynamicLoaderDarwinKernel (Process* process) :
+DynamicLoaderDarwinKernel::DynamicLoaderDarwinKernel (Process* process, lldb::addr_t kernel_addr) :
DynamicLoader(process),
+ m_kernel_load_address (kernel_addr),
m_kernel(),
m_kext_summary_header_ptr_addr (),
m_kext_summary_header_addr (),
m_kext_summary_header (),
- m_kext_summaries(),
+ m_known_kexts (),
m_mutex(Mutex::eMutexTypeRecursive),
m_break_id (LLDB_INVALID_BREAK_ID)
{
+ PlatformSP platform_sp(Platform::FindPlugin (process, "darwin-kernel"));
+ // Only select the darwin-kernel Platform if we've been asked to load kexts.
+ // It can take some time to scan over all of the kext info.plists and that
+ // shouldn't be done if kext loading is explicitly disabled.
+ if (platform_sp.get() && GetGlobalProperties()->GetLoadKexts())
+ {
+ process->GetTarget().SetPlatform (platform_sp);
+ }
}
//----------------------------------------------------------------------
@@ -210,148 +521,373 @@ DynamicLoaderDarwinKernel::Clear (bool c
if (clear_process)
m_process = NULL;
- m_kernel.Clear(false);
+ m_kernel.Clear();
+ m_known_kexts.clear();
m_kext_summary_header_ptr_addr.Clear();
m_kext_summary_header_addr.Clear();
- m_kext_summaries.clear();
m_break_id = LLDB_INVALID_BREAK_ID;
}
bool
-DynamicLoaderDarwinKernel::OSKextLoadedKextSummary::LoadImageAtFileAddress (Process *process)
+DynamicLoaderDarwinKernel::KextImageInfo::LoadImageAtFileAddress (Process *process)
{
if (IsLoaded())
return true;
- if (module_sp)
+ if (m_module_sp)
{
bool changed = false;
- if (module_sp->SetLoadAddress (process->GetTarget(), 0, changed))
- load_process_stop_id = process->GetStopID();
+ if (m_module_sp->SetLoadAddress (process->GetTarget(), 0, changed))
+ m_load_process_stop_id = process->GetStopID();
}
return false;
}
-bool
-DynamicLoaderDarwinKernel::OSKextLoadedKextSummary::LoadImageUsingMemoryModule (Process *process)
+void
+DynamicLoaderDarwinKernel::KextImageInfo::SetModule (ModuleSP module_sp)
{
- if (IsLoaded())
- return true;
+ m_module_sp = module_sp;
+ if (module_sp.get() && module_sp->GetObjectFile())
+ {
+ if (module_sp->GetObjectFile()->GetType() == ObjectFile::eTypeExecutable
+ && module_sp->GetObjectFile()->GetStrata() == ObjectFile::eStrataKernel)
+ {
+ m_kernel_image = true;
+ }
+ else
+ {
+ m_kernel_image = false;
+ }
+ }
+}
+
+ModuleSP
+DynamicLoaderDarwinKernel::KextImageInfo::GetModule ()
+{
+ return m_module_sp;
+}
+
+void
+DynamicLoaderDarwinKernel::KextImageInfo::SetLoadAddress (addr_t load_addr)
+{
+ m_load_address = load_addr;
+}
- bool uuid_is_valid = uuid.IsValid();
- bool memory_module_is_kernel = false;
+addr_t
+DynamicLoaderDarwinKernel::KextImageInfo::GetLoadAddress () const
+{
+ return m_load_address;
+}
- Target &target = process->GetTarget();
- ModuleSP memory_module_sp;
+uint64_t
+DynamicLoaderDarwinKernel::KextImageInfo::GetSize () const
+{
+ return m_size;
+}
+
+void
+DynamicLoaderDarwinKernel::KextImageInfo::SetSize (uint64_t size)
+{
+ m_size = size;
+}
- // If this is a kext and the user asked us to ignore kexts, don't try to load it.
- if (kernel_image == false && GetGlobalProperties()->GetLoadKexts() == false)
+uint32_t
+DynamicLoaderDarwinKernel::KextImageInfo::GetProcessStopId () const
+{
+ return m_load_process_stop_id;
+}
+
+void
+DynamicLoaderDarwinKernel::KextImageInfo::SetProcessStopId (uint32_t stop_id)
+{
+ m_load_process_stop_id = stop_id;
+}
+
+bool
+DynamicLoaderDarwinKernel::KextImageInfo::operator== (const KextImageInfo &rhs)
+{
+ if (m_uuid.IsValid() || rhs.GetUUID().IsValid())
{
+ if (m_uuid == rhs.GetUUID())
+ {
+ return true;
+ }
return false;
}
- // Use the memory module as the module if we have one
- if (address != LLDB_INVALID_ADDRESS)
+ if (m_name == rhs.GetName() && m_load_address == rhs.GetLoadAddress())
+ return true;
+
+ return false;
+}
+
+void
+DynamicLoaderDarwinKernel::KextImageInfo::SetName (const char *name)
+{
+ m_name = name;
+}
+
+std::string
+DynamicLoaderDarwinKernel::KextImageInfo::GetName () const
+{
+ return m_name;
+}
+
+void
+DynamicLoaderDarwinKernel::KextImageInfo::SetUUID (const UUID &uuid)
+{
+ m_uuid = uuid;
+}
+
+UUID
+DynamicLoaderDarwinKernel::KextImageInfo::GetUUID () const
+{
+ return m_uuid;
+}
+
+// Given the m_load_address from the kext summaries, and a UUID, try to create an in-memory
+// Module at that address. Require that the MemoryModule have a matching UUID and detect
+// if this MemoryModule is a kernel or a kext.
+//
+// Returns true if m_memory_module_sp is now set to a valid Module.
+
+bool
+DynamicLoaderDarwinKernel::KextImageInfo::ReadMemoryModule (Process *process)
+{
+ if (m_memory_module_sp.get() != NULL)
+ return true;
+ if (m_load_address == LLDB_INVALID_ADDRESS)
+ return false;
+
+ FileSpec file_spec;
+ file_spec.SetFile (m_name.c_str(), false);
+
+ ModuleSP memory_module_sp = process->ReadModuleFromMemory (file_spec, m_load_address);
+
+ if (memory_module_sp.get() == NULL)
+ return false;
+
+ bool is_kernel = false;
+ if (memory_module_sp->GetObjectFile())
{
- FileSpec file_spec;
- if (module_sp)
- file_spec = module_sp->GetFileSpec();
- else
- file_spec.SetFile (name, false);
-
- memory_module_sp = process->ReadModuleFromMemory (file_spec, address, false, false);
- if (memory_module_sp && !uuid_is_valid)
+ if (memory_module_sp->GetObjectFile()->GetType() == ObjectFile::eTypeExecutable
+ && memory_module_sp->GetObjectFile()->GetStrata() == ObjectFile::eStrataKernel)
{
- uuid = memory_module_sp->GetUUID();
- uuid_is_valid = uuid.IsValid();
+ is_kernel = true;
}
- if (memory_module_sp
- && memory_module_sp->GetObjectFile()
- && memory_module_sp->GetObjectFile()->GetType() == ObjectFile::eTypeExecutable
- && memory_module_sp->GetObjectFile()->GetStrata() == ObjectFile::eStrataKernel)
+ else if (memory_module_sp->GetObjectFile()->GetType() == ObjectFile::eTypeSharedLibrary)
{
- memory_module_is_kernel = true;
- if (memory_module_sp->GetArchitecture().IsValid())
- {
- target.SetArchitecture(memory_module_sp->GetArchitecture());
- }
+ is_kernel = false;
}
}
- if (!module_sp)
+ // If this is a kext, and the kernel specified what UUID we should find at this
+ // load address, require that the memory module have a matching UUID or something
+ // has gone wrong and we should discard it.
+ if (m_uuid.IsValid())
{
- if (uuid_is_valid)
+ if (m_uuid != memory_module_sp->GetUUID())
{
- const ModuleList &target_images = target.GetImages();
- module_sp = target_images.FindModule(uuid);
+ return false;
+ }
+ }
- if (!module_sp)
- {
- ModuleSpec module_spec;
- module_spec.GetUUID() = uuid;
- module_spec.GetArchitecture() = target.GetArchitecture();
+ // If the in-memory Module has a UUID, let's use that.
+ if (!m_uuid.IsValid() && memory_module_sp->GetUUID().IsValid())
+ {
+ m_uuid = memory_module_sp->GetUUID();
+ }
- // For the kernel, we really do need an on-disk file copy of the
- // binary.
- bool force_symbols_search = false;
- if (memory_module_is_kernel)
+ m_memory_module_sp = memory_module_sp;
+ m_kernel_image = is_kernel;
+ if (is_kernel)
+ {
+ if (memory_module_sp->GetArchitecture().IsValid())
+ {
+ process->GetTarget().SetArchitecture(memory_module_sp->GetArchitecture());
+ }
+ if (m_uuid.IsValid())
+ {
+ Module* exe_module = process->GetTarget().GetExecutableModulePointer();
+ if (exe_module && exe_module->GetUUID().IsValid())
+ {
+ if (m_uuid != exe_module->GetUUID())
{
- force_symbols_search = true;
+ Stream *s = &process->GetTarget().GetDebugger().GetOutputStream();
+ if (s)
+ {
+ char memory_module_uuidbuf[64];
+ char exe_module_uuidbuf[64];
+ s->Printf ("warning: Host-side kernel file has Mach-O UUID of %s but remote kernel has a UUID of %s -- a mismatched kernel file will result in a poor debugger experience.\n",
+ exe_module->GetUUID().GetAsCString(exe_module_uuidbuf, sizeof (exe_module_uuidbuf)),
+ m_uuid.GetAsCString(memory_module_uuidbuf, sizeof (memory_module_uuidbuf)));
+ s->Flush ();
+ }
}
+ }
+ }
+ }
+
+ return true;
+}
+
+bool
+DynamicLoaderDarwinKernel::KextImageInfo::IsKernel () const
+{
+ return m_kernel_image == true;
+}
+
+void
+DynamicLoaderDarwinKernel::KextImageInfo::SetIsKernel (bool is_kernel)
+{
+ m_kernel_image = is_kernel;
+}
+
+bool
+DynamicLoaderDarwinKernel::KextImageInfo::LoadImageUsingMemoryModule (Process *process)
+{
+ if (IsLoaded())
+ return true;
+
- if (Symbols::DownloadObjectAndSymbolFile (module_spec, force_symbols_search))
+ Target &target = process->GetTarget();
+
+ // If we don't have / can't create a memory module for this kext, don't try to load it - we won't
+ // have the correct segment load addresses.
+ if (!ReadMemoryModule (process))
+ {
+ return false;
+ }
+
+ bool uuid_is_valid = m_uuid.IsValid();
+
+ if (IsKernel() && uuid_is_valid && m_memory_module_sp.get())
+ {
+ Stream *s = &target.GetDebugger().GetOutputStream();
+ if (s)
+ {
+ char uuidbuf[64];
+ s->Printf ("Kernel UUID: %s\n", m_memory_module_sp->GetUUID().GetAsCString(uuidbuf, sizeof (uuidbuf)));
+ s->Printf ("Load Address: 0x%" PRIx64 "\n", m_load_address);
+ }
+ }
+
+ if (!m_module_sp)
+ {
+ // See if the kext has already been loaded into the target, probably by the user doing target modules add.
+ const ModuleList &target_images = target.GetImages();
+ m_module_sp = target_images.FindModule(m_uuid);
+
+ // Search for the kext on the local filesystem via the UUID
+ if (!m_module_sp && uuid_is_valid)
+ {
+ ModuleSpec module_spec;
+ module_spec.GetUUID() = m_uuid;
+ module_spec.GetArchitecture() = target.GetArchitecture();
+
+ // For the kernel, we really do need an on-disk file copy of the binary to do anything useful.
+ // This will force a clal to
+ if (IsKernel())
+ {
+ if (Symbols::DownloadObjectAndSymbolFile (module_spec, true))
{
if (module_spec.GetFileSpec().Exists())
{
- module_sp.reset(new Module (module_spec.GetFileSpec(), target.GetArchitecture()));
- if (module_sp.get() && module_sp->MatchesModuleSpec (module_spec))
+ m_module_sp.reset(new Module (module_spec.GetFileSpec(), target.GetArchitecture()));
+ if (m_module_sp.get() && m_module_sp->MatchesModuleSpec (module_spec))
{
ModuleList loaded_module_list;
- loaded_module_list.Append (module_sp);
+ loaded_module_list.Append (m_module_sp);
target.ModulesDidLoad (loaded_module_list);
}
}
}
-
- // Ask the Target to find this file on the local system, if possible.
- // This will search in the list of currently-loaded files, look in the
- // standard search paths on the system, and on a Mac it will try calling
- // the DebugSymbols framework with the UUID to find the binary via its
- // search methods.
- if (!module_sp)
+ }
+
+ // If the current platform is PlatformDarwinKernel, create a ModuleSpec with the filename set
+ // to be the bundle ID for this kext, e.g. "com.apple.filesystems.msdosfs", and ask the platform
+ // to find it.
+ PlatformSP platform_sp (target.GetPlatform());
+ if (platform_sp)
+ {
+ const char *pname = platform_sp->GetShortPluginName();
+ if (pname && strcmp (pname, "darwin-kernel") == 0)
{
- module_sp = target.GetSharedModule (module_spec);
+ ModuleSpec kext_bundle_module_spec(module_spec);
+ FileSpec kext_filespec(m_name.c_str(), false);
+ kext_bundle_module_spec.GetFileSpec() = kext_filespec;
+ platform_sp->GetSharedModule (kext_bundle_module_spec, m_module_sp, &target.GetExecutableSearchPaths(), NULL, NULL);
}
+ }
+
+ // Ask the Target to find this file on the local system, if possible.
+ // This will search in the list of currently-loaded files, look in the
+ // standard search paths on the system, and on a Mac it will try calling
+ // the DebugSymbols framework with the UUID to find the binary via its
+ // search methods.
+ if (!m_module_sp)
+ {
+ m_module_sp = target.GetSharedModule (module_spec);
+ }
- // If we managed to find a module, append it to the target's list of images
- if (module_sp && module_sp->GetUUID() == memory_module_sp->GetUUID())
+ if (IsKernel() && !m_module_sp)
+ {
+ Stream *s = &target.GetDebugger().GetOutputStream();
+ if (s)
{
- target.GetImages().Append(module_sp);
- if (memory_module_is_kernel && target.GetExecutableModulePointer() != module_sp.get())
- {
- target.SetExecutableModule (module_sp, false);
- }
+ s->Printf ("WARNING: Unable to locate kernel binary on this system.\n");
+ }
+ }
+ }
+
+ // If we managed to find a module, append it to the target's list of images.
+ // If we also have a memory module, require that they have matching UUIDs
+ if (m_module_sp)
+ {
+ bool uuid_match_ok = true;
+ if (m_memory_module_sp)
+ {
+ if (m_module_sp->GetUUID() != m_memory_module_sp->GetUUID())
+ {
+ uuid_match_ok = false;
+ }
+ }
+ if (uuid_match_ok)
+ {
+ target.GetImages().AppendIfNeeded(m_module_sp);
+ if (IsKernel() && target.GetExecutableModulePointer() != m_module_sp.get())
+ {
+ target.SetExecutableModule (m_module_sp, false);
}
}
}
}
+ if (!m_module_sp && !IsKernel() && m_uuid.IsValid() && !m_name.empty())
+ {
+ Stream *s = &target.GetDebugger().GetOutputStream();
+ if (s)
+ {
+ char uuidbuf[64];
+ s->Printf ("warning: Can't find binary/dSYM for %s (%s)\n",
+ m_name.c_str(), m_uuid.GetAsCString(uuidbuf, sizeof (uuidbuf)));
+ }
+ }
static ConstString g_section_name_LINKEDIT ("__LINKEDIT");
- if (memory_module_sp && module_sp)
+ if (m_memory_module_sp && m_module_sp)
{
- if (module_sp->GetUUID() == memory_module_sp->GetUUID())
+ if (m_module_sp->GetUUID() == m_memory_module_sp->GetUUID())
{
- ObjectFile *ondisk_object_file = module_sp->GetObjectFile();
- ObjectFile *memory_object_file = memory_module_sp->GetObjectFile();
+ ObjectFile *ondisk_object_file = m_module_sp->GetObjectFile();
+ ObjectFile *memory_object_file = m_memory_module_sp->GetObjectFile();
if (memory_object_file && ondisk_object_file)
{
- // Kexts are classified with a type of ObjectFile::eTypeSharedLibrary and
- // a strata of ObjectFile::eStrataKernel. Ignore __LINKEDIT for kexts
- const bool ignore_linkedit = ondisk_object_file->GetType() == ObjectFile::eTypeSharedLibrary;
+ // The memory_module for kexts may have an invalid __LINKEDIT seg; skip it.
+ const bool ignore_linkedit = !IsKernel ();
SectionList *ondisk_section_list = ondisk_object_file->GetSectionList ();
SectionList *memory_section_list = memory_object_file->GetSectionList ();
@@ -391,48 +927,45 @@ DynamicLoaderDarwinKernel::OSKextLoadedK
}
}
if (num_sections_loaded > 0)
- load_process_stop_id = process->GetStopID();
+ m_load_process_stop_id = process->GetStopID();
else
- module_sp.reset(); // No sections were loaded
+ m_module_sp.reset(); // No sections were loaded
}
else
- module_sp.reset(); // One or both section lists
+ m_module_sp.reset(); // One or both section lists
}
else
- module_sp.reset(); // One or both object files missing
+ m_module_sp.reset(); // One or both object files missing
}
else
- module_sp.reset(); // UUID mismatch
+ m_module_sp.reset(); // UUID mismatch
}
bool is_loaded = IsLoaded();
- if (so_address.IsValid())
- {
- if (is_loaded)
- so_address.SetLoadAddress (address, &target);
- else
- target.GetImages().ResolveFileAddress (address, so_address);
-
- }
-
- if (is_loaded && module_sp && memory_module_is_kernel)
+ if (is_loaded && m_module_sp && IsKernel())
{
Stream *s = &target.GetDebugger().GetOutputStream();
if (s)
{
- char uuidbuf[64];
- s->Printf ("Kernel UUID: %s\n", module_sp->GetUUID().GetAsCString(uuidbuf, sizeof (uuidbuf)));
- s->Printf ("Load Address: 0x%" PRIx64 "\n", address);
- if (module_sp->GetFileSpec().GetDirectory().IsEmpty())
+ ObjectFile *kernel_object_file = m_module_sp->GetObjectFile();
+ if (kernel_object_file)
+ {
+ addr_t file_address = kernel_object_file->GetHeaderAddress().GetFileAddress();
+ if (m_load_address != LLDB_INVALID_ADDRESS && file_address != LLDB_INVALID_ADDRESS)
+ {
+ s->Printf ("Kernel slid 0x%" PRIx64 " in memory.\n", m_load_address - file_address);
+ }
+ }
+ if (m_module_sp->GetFileSpec().GetDirectory().IsEmpty())
{
- s->Printf ("Loaded kernel file %s\n", module_sp->GetFileSpec().GetFilename().AsCString());
+ s->Printf ("Loaded kernel file %s\n", m_module_sp->GetFileSpec().GetFilename().AsCString());
}
else
{
s->Printf ("Loaded kernel file %s/%s\n",
- module_sp->GetFileSpec().GetDirectory().AsCString(),
- module_sp->GetFileSpec().GetFilename().AsCString());
+ m_module_sp->GetFileSpec().GetDirectory().AsCString(),
+ m_module_sp->GetFileSpec().GetFilename().AsCString());
}
s->Flush ();
}
@@ -441,26 +974,32 @@ DynamicLoaderDarwinKernel::OSKextLoadedK
}
uint32_t
-DynamicLoaderDarwinKernel::OSKextLoadedKextSummary::GetAddressByteSize ()
+DynamicLoaderDarwinKernel::KextImageInfo::GetAddressByteSize ()
{
- if (module_sp)
- return module_sp->GetArchitecture().GetAddressByteSize();
+ if (m_memory_module_sp)
+ return m_memory_module_sp->GetArchitecture().GetAddressByteSize();
+ if (m_module_sp)
+ return m_module_sp->GetArchitecture().GetAddressByteSize();
return 0;
}
lldb::ByteOrder
-DynamicLoaderDarwinKernel::OSKextLoadedKextSummary::GetByteOrder()
+DynamicLoaderDarwinKernel::KextImageInfo::GetByteOrder()
{
- if (module_sp)
- return module_sp->GetArchitecture().GetByteOrder();
+ if (m_memory_module_sp)
+ return m_memory_module_sp->GetArchitecture().GetByteOrder();
+ if (m_module_sp)
+ return m_module_sp->GetArchitecture().GetByteOrder();
return lldb::endian::InlHostByteOrder();
}
lldb_private::ArchSpec
-DynamicLoaderDarwinKernel::OSKextLoadedKextSummary::GetArchitecture () const
+DynamicLoaderDarwinKernel::KextImageInfo::GetArchitecture () const
{
- if (module_sp)
- return module_sp->GetArchitecture();
+ if (m_memory_module_sp)
+ return m_memory_module_sp->GetArchitecture();
+ if (m_module_sp)
+ return m_module_sp->GetArchitecture();
return lldb_private::ArchSpec ();
}
@@ -476,53 +1015,52 @@ DynamicLoaderDarwinKernel::LoadKernelMod
{
if (!m_kext_summary_header_ptr_addr.IsValid())
{
- m_kernel.Clear(false);
- m_kernel.module_sp = m_process->GetTarget().GetExecutableModule();
- m_kernel.kernel_image = true;
+ m_kernel.Clear();
+ m_kernel.SetModule (m_process->GetTarget().GetExecutableModule());
+ m_kernel.SetIsKernel(true);
ConstString kernel_name("mach_kernel");
- if (m_kernel.module_sp.get()
- && m_kernel.module_sp->GetObjectFile()
- && !m_kernel.module_sp->GetObjectFile()->GetFileSpec().GetFilename().IsEmpty())
+ if (m_kernel.GetModule().get()
+ && m_kernel.GetModule()->GetObjectFile()
+ && !m_kernel.GetModule()->GetObjectFile()->GetFileSpec().GetFilename().IsEmpty())
{
- kernel_name = m_kernel.module_sp->GetObjectFile()->GetFileSpec().GetFilename();
+ kernel_name = m_kernel.GetModule()->GetObjectFile()->GetFileSpec().GetFilename();
}
- strncpy (m_kernel.name, kernel_name.AsCString(), sizeof(m_kernel.name));
- m_kernel.name[sizeof (m_kernel.name) - 1] = '\0';
+ m_kernel.SetName (kernel_name.AsCString());
- if (m_kernel.address == LLDB_INVALID_ADDRESS)
+ if (m_kernel.GetLoadAddress() == LLDB_INVALID_ADDRESS)
{
- m_kernel.address = m_process->GetImageInfoAddress ();
- if (m_kernel.address == LLDB_INVALID_ADDRESS && m_kernel.module_sp)
+ m_kernel.SetLoadAddress(m_kernel_load_address);
+ if (m_kernel.GetLoadAddress() == LLDB_INVALID_ADDRESS && m_kernel.GetModule())
{
// We didn't get a hint from the process, so we will
// try the kernel at the address that it exists at in
// the file if we have one
- ObjectFile *kernel_object_file = m_kernel.module_sp->GetObjectFile();
+ ObjectFile *kernel_object_file = m_kernel.GetModule()->GetObjectFile();
if (kernel_object_file)
{
addr_t load_address = kernel_object_file->GetHeaderAddress().GetLoadAddress(&m_process->GetTarget());
addr_t file_address = kernel_object_file->GetHeaderAddress().GetFileAddress();
if (load_address != LLDB_INVALID_ADDRESS && load_address != 0)
{
- m_kernel.address = load_address;
+ m_kernel.SetLoadAddress (load_address);
if (load_address != file_address)
{
// Don't accidentally relocate the kernel to the File address --
// the Load address has already been set to its actual in-memory address.
// Mark it as IsLoaded.
- m_kernel.load_process_stop_id = m_process->GetStopID();
+ m_kernel.SetProcessStopId (m_process->GetStopID());
}
}
else
{
- m_kernel.address = file_address;
+ m_kernel.SetLoadAddress(file_address);
}
}
}
}
- if (m_kernel.address != LLDB_INVALID_ADDRESS)
+ if (m_kernel.GetLoadAddress() != LLDB_INVALID_ADDRESS)
{
if (!m_kernel.LoadImageUsingMemoryModule (m_process))
{
@@ -530,10 +1068,10 @@ DynamicLoaderDarwinKernel::LoadKernelMod
}
}
- if (m_kernel.IsLoaded() && m_kernel.module_sp)
+ if (m_kernel.IsLoaded() && m_kernel.GetModule())
{
static ConstString kext_summary_symbol ("gLoadedKextSummaries");
- const Symbol *symbol = m_kernel.module_sp->FindFirstSymbolWithNameAndType (kext_summary_symbol, eSymbolTypeData);
+ const Symbol *symbol = m_kernel.GetModule()->FindFirstSymbolWithNameAndType (kext_summary_symbol, eSymbolTypeData);
if (symbol)
{
m_kext_summary_header_ptr_addr = symbol->GetAddress();
@@ -543,7 +1081,7 @@ DynamicLoaderDarwinKernel::LoadKernelMod
}
else
{
- m_kernel.Clear(false);
+ m_kernel.Clear();
}
}
}
@@ -568,14 +1106,14 @@ DynamicLoaderDarwinKernel::BreakpointHit
user_id_t break_id,
user_id_t break_loc_id)
{
- LogSP log(GetLogIfAnyCategoriesSet (LIBLLDB_LOG_DYNAMIC_LOADER));
+ Log *log(GetLogIfAnyCategoriesSet (LIBLLDB_LOG_DYNAMIC_LOADER));
if (log)
log->Printf ("DynamicLoaderDarwinKernel::BreakpointHit (...)\n");
ReadAllKextSummaries ();
if (log)
- PutToLog(log.get());
+ PutToLog(log);
return GetStopWhenImagesChange();
}
@@ -588,7 +1126,6 @@ DynamicLoaderDarwinKernel::ReadKextSumma
// the all image infos is already valid for this process stop ID
- m_kext_summaries.clear();
if (m_kext_summary_header_ptr_addr.IsValid())
{
const uint32_t addr_size = m_kernel.GetAddressByteSize ();
@@ -612,7 +1149,7 @@ DynamicLoaderDarwinKernel::ReadKextSumma
const size_t bytes_read = m_process->GetTarget().ReadMemory (m_kext_summary_header_addr, prefer_file_cache, buf, count, error);
if (bytes_read == count)
{
- uint32_t offset = 0;
+ lldb::offset_t offset = 0;
m_kext_summary_header.version = data.GetU32(&offset);
if (m_kext_summary_header.version >= 2)
{
@@ -633,72 +1170,194 @@ DynamicLoaderDarwinKernel::ReadKextSumma
return false;
}
+// We've either (a) just attached to a new kernel, or (b) the kexts-changed breakpoint was hit
+// and we need to figure out what kexts have been added or removed.
+// Read the kext summaries from the inferior kernel memory, compare them against the
+// m_known_kexts vector and update the m_known_kexts vector as needed to keep in sync with the
+// inferior.
bool
-DynamicLoaderDarwinKernel::ParseKextSummaries (const Address &kext_summary_addr,
- uint32_t count)
+DynamicLoaderDarwinKernel::ParseKextSummaries (const Address &kext_summary_addr, uint32_t count)
{
- OSKextLoadedKextSummary::collection kext_summaries;
- LogSP log(GetLogIfAnyCategoriesSet (LIBLLDB_LOG_DYNAMIC_LOADER));
+ KextImageInfo::collection kext_summaries;
+ Log *log(GetLogIfAnyCategoriesSet (LIBLLDB_LOG_DYNAMIC_LOADER));
if (log)
- log->Printf ("Adding %d modules.\n", count);
+ log->Printf ("Kexts-changed breakpoint hit, there are %d kexts currently.\n", count);
Mutex::Locker locker(m_mutex);
if (!ReadKextSummaries (kext_summary_addr, count, kext_summaries))
return false;
- Stream *s = &m_process->GetTarget().GetDebugger().GetOutputStream();
- if (s)
- s->Printf ("Loading %d kext modules ", count);
- for (uint32_t i = 0; i < count; i++)
+ // read the plugin.dynamic-loader.darwin-kernel.load-kexts setting -- if the user requested no
+ // kext loading, don't print any messages about kexts & don't try to read them.
+ const bool load_kexts = GetGlobalProperties()->GetLoadKexts();
+
+ // By default, all kexts we've loaded in the past are marked as "remove" and all of the kexts
+ // we just found out about from ReadKextSummaries are marked as "add".
+ std::vector<bool> to_be_removed(m_known_kexts.size(), true);
+ std::vector<bool> to_be_added(count, true);
+
+ int number_of_new_kexts_being_added = 0;
+ int number_of_old_kexts_being_removed = m_known_kexts.size();
+
+ const uint32_t new_kexts_size = kext_summaries.size();
+ const uint32_t old_kexts_size = m_known_kexts.size();
+
+ // The m_known_kexts vector may have entries that have been Cleared,
+ // or are a kernel.
+ for (uint32_t old_kext = 0; old_kext < old_kexts_size; old_kext++)
+ {
+ bool ignore = false;
+ KextImageInfo &image_info = m_known_kexts[old_kext];
+ if (image_info.IsKernel())
+ {
+ ignore = true;
+ }
+ else if (image_info.GetLoadAddress() == LLDB_INVALID_ADDRESS && !image_info.GetModule())
+ {
+ ignore = true;
+ }
+
+ if (ignore)
+ {
+ number_of_old_kexts_being_removed--;
+ to_be_removed[old_kext] = false;
+ }
+ }
+
+ // Scan over the list of kexts we just read from the kernel, note those that
+ // need to be added and those already loaded.
+ for (uint32_t new_kext = 0; new_kext < new_kexts_size; new_kext++)
{
- if (!kext_summaries[i].LoadImageUsingMemoryModule (m_process))
- kext_summaries[i].LoadImageAtFileAddress (m_process);
+ bool add_this_one = true;
+ for (uint32_t old_kext = 0; old_kext < old_kexts_size; old_kext++)
+ {
+ if (m_known_kexts[old_kext] == kext_summaries[new_kext])
+ {
+ // We already have this kext, don't re-load it.
+ to_be_added[new_kext] = false;
+ // This kext is still present, do not remove it.
+ to_be_removed[old_kext] = false;
- if (s)
- s->Printf (".");
+ number_of_old_kexts_being_removed--;
+ add_this_one = false;
+ break;
+ }
+ }
+ if (add_this_one)
+ {
+ number_of_new_kexts_being_added++;
+ }
+ }
+
+ if (number_of_new_kexts_being_added == 0 && number_of_old_kexts_being_removed == 0)
+ return true;
- if (log)
- kext_summaries[i].PutToLog (log.get());
+ Stream *s = &m_process->GetTarget().GetDebugger().GetOutputStream();
+ if (s && load_kexts)
+ {
+ if (number_of_new_kexts_being_added > 0 && number_of_old_kexts_being_removed > 0)
+ {
+ s->Printf ("Loading %d kext modules and unloading %d kext modules ", number_of_new_kexts_being_added, number_of_old_kexts_being_removed);
+ }
+ else if (number_of_new_kexts_being_added > 0)
+ {
+ s->Printf ("Loading %d kext modules ", number_of_new_kexts_being_added);
+ }
+ else if (number_of_old_kexts_being_removed > 0)
+ {
+ s->Printf ("Unloading %d kext modules ", number_of_old_kexts_being_removed);
+ }
}
- if (s)
+
+ if (log)
{
- s->Printf (" done.\n");
- s->Flush ();
+ if (load_kexts)
+ {
+ log->Printf ("DynamicLoaderDarwinKernel::ParseKextSummaries: %d kexts added, %d kexts removed", number_of_new_kexts_being_added, number_of_old_kexts_being_removed);
+ }
+ else
+ {
+ log->Printf ("DynamicLoaderDarwinKernel::ParseKextSummaries kext loading is disabled, else would have %d kexts added, %d kexts removed", number_of_new_kexts_being_added, number_of_old_kexts_being_removed);
+ }
}
- bool return_value = AddModulesUsingImageInfos (kext_summaries);
- return return_value;
-}
-// Adds the modules in image_infos to m_kext_summaries.
-// NB don't call this passing in m_kext_summaries.
+ if (number_of_new_kexts_being_added > 0)
+ {
+ ModuleList loaded_module_list;
-bool
-DynamicLoaderDarwinKernel::AddModulesUsingImageInfos (OSKextLoadedKextSummary::collection &image_infos)
-{
- // Now add these images to the main list.
- ModuleList loaded_module_list;
-
- for (uint32_t idx = 0; idx < image_infos.size(); ++idx)
+ const uint32_t num_of_new_kexts = kext_summaries.size();
+ for (uint32_t new_kext = 0; new_kext < num_of_new_kexts; new_kext++)
+ {
+ if (to_be_added[new_kext] == true)
+ {
+ KextImageInfo &image_info = kext_summaries[new_kext];
+ if (load_kexts)
+ {
+ if (!image_info.LoadImageUsingMemoryModule (m_process))
+ {
+ image_info.LoadImageAtFileAddress (m_process);
+ }
+ }
+
+ m_known_kexts.push_back(image_info);
+
+ if (image_info.GetModule() && m_process->GetStopID() == image_info.GetProcessStopId())
+ loaded_module_list.AppendIfNeeded (image_info.GetModule());
+
+ if (s && load_kexts)
+ s->Printf (".");
+
+ if (log)
+ kext_summaries[new_kext].PutToLog (log);
+ }
+ }
+ m_process->GetTarget().ModulesDidLoad (loaded_module_list);
+ }
+
+ if (number_of_old_kexts_being_removed > 0)
{
- OSKextLoadedKextSummary &image_info = image_infos[idx];
- m_kext_summaries.push_back(image_info);
-
- if (image_info.module_sp && m_process->GetStopID() == image_info.load_process_stop_id)
- loaded_module_list.AppendIfNeeded (image_infos[idx].module_sp);
+ ModuleList loaded_module_list;
+ const uint32_t num_of_old_kexts = m_known_kexts.size();
+ for (uint32_t old_kext = 0; old_kext < num_of_old_kexts; old_kext++)
+ {
+ ModuleList unloaded_module_list;
+ if (to_be_removed[old_kext])
+ {
+ KextImageInfo &image_info = m_known_kexts[old_kext];
+ // You can't unload the kernel.
+ if (!image_info.IsKernel())
+ {
+ if (image_info.GetModule())
+ {
+ unloaded_module_list.AppendIfNeeded (image_info.GetModule());
+ }
+ if (s)
+ s->Printf (".");
+ image_info.Clear();
+ // should pull it out of the KextImageInfos vector but that would mutate the list and invalidate
+ // the to_be_removed bool vector; leaving it in place once Cleared() is relatively harmless.
+ }
+ }
+ m_process->GetTarget().ModulesDidUnload (unloaded_module_list);
+ }
}
-
- m_process->GetTarget().ModulesDidLoad (loaded_module_list);
+
+ if (s && load_kexts)
+ {
+ s->Printf (" done.\n");
+ s->Flush ();
+ }
+
return true;
}
-
uint32_t
DynamicLoaderDarwinKernel::ReadKextSummaries (const Address &kext_summary_addr,
uint32_t image_infos_count,
- OSKextLoadedKextSummary::collection &image_infos)
+ KextImageInfo::collection &image_infos)
{
const ByteOrder endian = m_kernel.GetByteOrder();
const uint32_t addr_size = m_kernel.GetAddressByteSize();
@@ -723,27 +1382,15 @@ DynamicLoaderDarwinKernel::ReadKextSumma
i < image_infos.size() && extractor.ValidOffsetForDataOfSize(kext_summary_offset, m_kext_summary_header.entry_size);
++i, kext_summary_offset += m_kext_summary_header.entry_size)
{
- uint32_t offset = kext_summary_offset;
+ lldb::offset_t offset = kext_summary_offset;
const void *name_data = extractor.GetData(&offset, KERNEL_MODULE_MAX_NAME);
if (name_data == NULL)
break;
- memcpy (image_infos[i].name, name_data, KERNEL_MODULE_MAX_NAME);
- image_infos[i].uuid.SetBytes(extractor.GetData (&offset, 16));
- image_infos[i].address = extractor.GetU64(&offset);
- if (!image_infos[i].so_address.SetLoadAddress (image_infos[i].address, &m_process->GetTarget()))
- m_process->GetTarget().GetImages().ResolveFileAddress (image_infos[i].address, image_infos[i].so_address);
- image_infos[i].size = extractor.GetU64(&offset);
- image_infos[i].version = extractor.GetU64(&offset);
- image_infos[i].load_tag = extractor.GetU32(&offset);
- image_infos[i].flags = extractor.GetU32(&offset);
- if ((offset - kext_summary_offset) < m_kext_summary_header.entry_size)
- {
- image_infos[i].reference_list = extractor.GetU64(&offset);
- }
- else
- {
- image_infos[i].reference_list = 0;
- }
+ image_infos[i].SetName ((const char *) name_data);
+ UUID uuid (extractor.GetData (&offset, 16), 16);
+ image_infos[i].SetUUID (uuid);
+ image_infos[i].SetLoadAddress (extractor.GetU64(&offset));
+ image_infos[i].SetSize (extractor.GetU64(&offset));
}
if (i < image_infos.size())
image_infos.resize(i);
@@ -758,8 +1405,6 @@ DynamicLoaderDarwinKernel::ReadKextSumma
bool
DynamicLoaderDarwinKernel::ReadAllKextSummaries ()
{
- LogSP log(GetLogIfAnyCategoriesSet (LIBLLDB_LOG_DYNAMIC_LOADER));
-
Mutex::Locker locker(m_mutex);
if (ReadKextSummaryHeader ())
@@ -770,7 +1415,7 @@ DynamicLoaderDarwinKernel::ReadAllKextSu
summary_addr.Slide(m_kext_summary_header.GetSize());
if (!ParseKextSummaries (summary_addr, m_kext_summary_header.entry_count))
{
- m_kext_summaries.clear();
+ m_known_kexts.clear();
}
return true;
}
@@ -782,13 +1427,13 @@ DynamicLoaderDarwinKernel::ReadAllKextSu
// Dump an image info structure to the file handle provided.
//----------------------------------------------------------------------
void
-DynamicLoaderDarwinKernel::OSKextLoadedKextSummary::PutToLog (Log *log) const
+DynamicLoaderDarwinKernel::KextImageInfo::PutToLog (Log *log) const
{
if (log == NULL)
return;
- const uint8_t *u = (uint8_t *)uuid.GetBytes();
+ const uint8_t *u = (uint8_t *) m_uuid.GetBytes();
- if (address == LLDB_INVALID_ADDRESS)
+ if (m_load_address == LLDB_INVALID_ADDRESS)
{
if (u)
{
@@ -797,26 +1442,25 @@ DynamicLoaderDarwinKernel::OSKextLoadedK
u[ 4], u[ 5], u[ 6], u[ 7],
u[ 8], u[ 9], u[10], u[11],
u[12], u[13], u[14], u[15],
- name);
+ m_name.c_str());
}
else
- log->Printf("\tname=\"%s\" (UNLOADED)", name);
+ log->Printf("\tname=\"%s\" (UNLOADED)", m_name.c_str());
}
else
{
if (u)
{
- log->Printf("\taddr=0x%16.16" PRIx64 " size=0x%16.16" PRIx64 " version=0x%16.16" PRIx64 " load-tag=0x%8.8x flags=0x%8.8x ref-list=0x%16.16" PRIx64 " uuid=%2.2X%2.2X%2.2X%2.2X-%2.2X%2.2X-%2.2X%2.2X-%2.2X%2.2X-%2.2X%2.2X%2.2X%2.2X%2.2X%2.2X name=\"%s\"",
- address, size, version, load_tag, flags, reference_list,
+ log->Printf("\taddr=0x%16.16" PRIx64 " size=0x%16.16" PRIx64 " uuid=%2.2X%2.2X%2.2X%2.2X-%2.2X%2.2X-%2.2X%2.2X-%2.2X%2.2X-%2.2X%2.2X%2.2X%2.2X%2.2X%2.2X name=\"%s\"",
+ m_load_address, m_size,
u[ 0], u[ 1], u[ 2], u[ 3], u[ 4], u[ 5], u[ 6], u[ 7],
u[ 8], u[ 9], u[10], u[11], u[12], u[13], u[14], u[15],
- name);
+ m_name.c_str());
}
else
{
- log->Printf("\t[0x%16.16" PRIx64 " - 0x%16.16" PRIx64 ") version=0x%16.16" PRIx64 " load-tag=0x%8.8x flags=0x%8.8x ref-list=0x%16.16" PRIx64 " name=\"%s\"",
- address, address+size, version, load_tag, flags, reference_list,
- name);
+ log->Printf("\t[0x%16.16" PRIx64 " - 0x%16.16" PRIx64 ") name=\"%s\"",
+ m_load_address, m_load_address+m_size, m_name.c_str());
}
}
}
@@ -839,12 +1483,12 @@ DynamicLoaderDarwinKernel::PutToLog(Log
m_kext_summary_header.entry_count);
size_t i;
- const size_t count = m_kext_summaries.size();
+ const size_t count = m_known_kexts.size();
if (count > 0)
{
log->PutCString("Loaded:");
for (i = 0; i<count; i++)
- m_kext_summaries[i].PutToLog(log);
+ m_known_kexts[i].PutToLog(log);
}
}
@@ -859,7 +1503,7 @@ DynamicLoaderDarwinKernel::PrivateInitia
void
DynamicLoaderDarwinKernel::SetNotificationBreakpointIfNeeded ()
{
- if (m_break_id == LLDB_INVALID_BREAK_ID && m_kernel.module_sp)
+ if (m_break_id == LLDB_INVALID_BREAK_ID && m_kernel.GetModule())
{
DEBUG_PRINTF("DynamicLoaderDarwinKernel::%s() process state = %s\n", __FUNCTION__, StateAsCString(m_process->GetState()));
@@ -867,7 +1511,7 @@ DynamicLoaderDarwinKernel::SetNotificati
const bool internal_bp = true;
const LazyBool skip_prologue = eLazyBoolNo;
FileSpecList module_spec_list;
- module_spec_list.Append (m_kernel.module_sp->GetFileSpec());
+ module_spec_list.Append (m_kernel.GetModule()->GetFileSpec());
Breakpoint *bp = m_process->GetTarget().CreateBreakpoint (&module_spec_list,
NULL,
"OSKextLoadedKextSummariesUpdated",
@@ -915,7 +1559,7 @@ ThreadPlanSP
DynamicLoaderDarwinKernel::GetStepThroughTrampolinePlan (Thread &thread, bool stop_others)
{
ThreadPlanSP thread_plan_sp;
- LogSP log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP));
+ Log *log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP));
if (log)
log->Printf ("Could not find symbol for step through.");
return thread_plan_sp;
Modified: lldb/branches/windows/source/Plugins/DynamicLoader/Darwin-Kernel/DynamicLoaderDarwinKernel.h
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/windows/source/Plugins/DynamicLoader/Darwin-Kernel/DynamicLoaderDarwinKernel.h?rev=179679&r1=179678&r2=179679&view=diff
==============================================================================
--- lldb/branches/windows/source/Plugins/DynamicLoader/Darwin-Kernel/DynamicLoaderDarwinKernel.h (original)
+++ lldb/branches/windows/source/Plugins/DynamicLoader/Darwin-Kernel/DynamicLoaderDarwinKernel.h Wed Apr 17 03:38:48 2013
@@ -50,10 +50,14 @@ public:
static void
DebuggerInitialize (lldb_private::Debugger &debugger);
- DynamicLoaderDarwinKernel (lldb_private::Process *process);
+ DynamicLoaderDarwinKernel (lldb_private::Process *process, lldb::addr_t kernel_addr);
+
+ static lldb::addr_t
+ SearchForDarwinKernel (lldb_private::Process *process);
virtual
~DynamicLoaderDarwinKernel ();
+
//------------------------------------------------------------------
/// Called after attaching a process.
///
@@ -92,7 +96,7 @@ protected:
void
PrivateProcessStateChanged (lldb_private::Process *process,
lldb::StateType state);
-
+
void
UpdateIfNeeded();
@@ -112,8 +116,8 @@ protected:
lldb::user_id_t break_loc_id);
bool
- BreakpointHit (lldb_private::StoppointCallbackContext *context,
- lldb::user_id_t break_id,
+ BreakpointHit (lldb_private::StoppointCallbackContext *context,
+ lldb::user_id_t break_id,
lldb::user_id_t break_loc_id);
uint32_t
GetAddrByteSize()
@@ -133,60 +137,51 @@ protected:
// 4 byte flags
KERNEL_MODULE_ENTRY_SIZE_VERSION_1 = 64u + 16u + 8u + 8u + 8u + 4u + 4u
};
-
- struct OSKextLoadedKextSummary
+
+ // class KextImageInfo represents a single kext or kernel binary image.
+ // The class was designed to hold the information from the OSKextLoadedKextSummary
+ // structure (in libkern/libkern/OSKextLibPrivate.h from xnu). The kernel maintains
+ // a list of loded kexts in memory (the OSKextLoadedKextSummaryHeader structure,
+ // which points to an array of OSKextLoadedKextSummary's).
+ //
+ // A KextImageInfos may have -
+ //
+ // 1. The load address, name, UUID, and size of a kext/kernel binary in memory
+ // (read straight out of the kernel's list-of-kexts loaded)
+ // 2. A ModuleSP based on a MemoryModule read out of the kernel's memory
+ // (very unlikely to have any symbolic information)
+ // 3. A ModuleSP for an on-disk copy of the kext binary, possibly with debug info
+ // or a dSYM
+ //
+ // For performance reasons, the developer may prefer that lldb not load the kexts out
+ // of memory at the start of a kernel session. But we should build up / maintain a
+ // list of kexts that the kernel has told us about so we can relocate a kext module
+ // later if the user explicitly adds it to the target.
+
+ class KextImageInfo
{
- char name[KERNEL_MODULE_MAX_NAME];
- lldb::ModuleSP module_sp;
- uint32_t load_process_stop_id;
- lldb_private::UUID uuid; // UUID for this dylib if it has one, else all zeros
- lldb_private::Address so_address; // The section offset address for this kext in case it can be read from object files
- uint64_t address;
- uint64_t size;
- uint64_t version;
- uint32_t load_tag;
- uint32_t flags;
- uint64_t reference_list;
- bool kernel_image; // true if this is the kernel, false if this is a kext
-
- OSKextLoadedKextSummary() :
- module_sp (),
- load_process_stop_id (UINT32_MAX),
- uuid (),
- so_address (),
- address (LLDB_INVALID_ADDRESS),
- size (0),
- version (0),
- load_tag (0),
- flags (0),
- reference_list (0),
- kernel_image (false)
- {
- name[0] = '\0';
- }
-
- bool
- IsLoaded ()
- {
- return load_process_stop_id != UINT32_MAX;
- }
+ public:
+ KextImageInfo () :
+ m_name (),
+ m_module_sp (),
+ m_memory_module_sp (),
+ m_load_process_stop_id (UINT32_MAX),
+ m_uuid (),
+ m_load_address (LLDB_INVALID_ADDRESS),
+ m_size (0),
+ m_kernel_image (false)
+ { }
void
- Clear (bool load_cmd_data_only)
+ Clear ()
{
- if (!load_cmd_data_only)
- {
- so_address.Clear();
- address = LLDB_INVALID_ADDRESS;
- size = 0;
- version = 0;
- load_tag = 0;
- flags = 0;
- reference_list = 0;
- name[0] = '\0';
- }
- module_sp.reset();
- load_process_stop_id = UINT32_MAX;
+ m_load_address = LLDB_INVALID_ADDRESS;
+ m_size = 0;
+ m_name.clear ();
+ m_uuid.Clear();
+ m_module_sp.reset();
+ m_memory_module_sp.reset();
+ m_load_process_stop_id = UINT32_MAX;
}
bool
@@ -194,42 +189,88 @@ protected:
bool
LoadImageUsingMemoryModule (lldb_private::Process *process);
-
-// bool
-// operator == (const OSKextLoadedKextSummary& rhs) const
-// {
-// return address == rhs.address
-// && size == rhs.size
-// //&& module_sp.get() == rhs.module_sp.get()
-// && uuid == rhs.uuid
-// && version == rhs.version
-// && load_tag == rhs.load_tag
-// && flags == rhs.flags
-// && reference_list == rhs.reference_list
-// && strncmp (name, rhs.name, KERNEL_MODULE_MAX_NAME) == 0;
-// }
-//
+
bool
- UUIDValid() const
+ IsLoaded ()
{
- return uuid.IsValid();
+ return m_load_process_stop_id != UINT32_MAX;
}
+ void
+ SetLoadAddress (lldb::addr_t load_addr); // Address of the Mach-O header for this binary
+
+ lldb::addr_t
+ GetLoadAddress () const; // Address of the Mach-O header for this binary
+
+ lldb_private::UUID
+ GetUUID () const;
+
+ void
+ SetUUID (const lldb_private::UUID &uuid);
+
+ void
+ SetName (const char *);
+
+ std::string
+ GetName () const;
+
+ void
+ SetModule (lldb::ModuleSP module);
+
+ lldb::ModuleSP
+ GetModule ();
+
+ // try to fill in m_memory_module_sp from memory based on the m_load_address
+ bool
+ ReadMemoryModule (lldb_private::Process *process);
+
+ bool
+ IsKernel () const; // true if this is the mach_kernel; false if this is a kext
+
+ void
+ SetIsKernel (bool is_kernel);
+
+ uint64_t
+ GetSize () const;
+
+ void
+ SetSize (uint64_t size);
+
uint32_t
- GetAddressByteSize ();
+ GetProcessStopId () const; // the stop-id when this binary was first noticed
+
+ void
+ SetProcessStopId (uint32_t stop_id);
+
+ bool
+ operator== (const KextImageInfo &rhs);
+
+ uint32_t
+ GetAddressByteSize (); // as determined by Mach-O header
lldb::ByteOrder
- GetByteOrder();
+ GetByteOrder(); // as determined by Mach-O header
lldb_private::ArchSpec
- GetArchitecture () const;
+ GetArchitecture () const; // as determined by Mach-O header
void
PutToLog (lldb_private::Log *log) const;
- typedef std::vector<OSKextLoadedKextSummary> collection;
+ typedef std::vector<KextImageInfo> collection;
typedef collection::iterator iterator;
typedef collection::const_iterator const_iterator;
+
+ private:
+ std::string m_name;
+ lldb::ModuleSP m_module_sp;
+ lldb::ModuleSP m_memory_module_sp;
+ uint32_t m_load_process_stop_id; // the stop-id when this module was added to the Target
+ lldb_private::UUID m_uuid; // UUID for this dylib if it has one, else all zeros
+ lldb::addr_t m_load_address;
+ uint64_t m_size;
+ bool m_kernel_image; // true if this is the kernel, false if this is a kext
+
};
struct OSKextLoadedKextSummaryHeader
@@ -257,7 +298,7 @@ protected:
default: break;
}
// Version 2 and above has version, entry_size, entry_count, and reserved
- return 16;
+ return 16;
}
void
@@ -290,31 +331,45 @@ protected:
bool
ReadKextSummaryHeader ();
-
+
bool
- ParseKextSummaries (const lldb_private::Address &kext_summary_addr,
+ ParseKextSummaries (const lldb_private::Address &kext_summary_addr,
uint32_t count);
-
- bool
- AddModulesUsingImageInfos (OSKextLoadedKextSummary::collection &image_infos);
-
+
void
- UpdateImageInfosHeaderAndLoadCommands(OSKextLoadedKextSummary::collection &image_infos,
- uint32_t infos_count,
+ UpdateImageInfosHeaderAndLoadCommands(KextImageInfo::collection &image_infos,
+ uint32_t infos_count,
bool update_executable);
uint32_t
ReadKextSummaries (const lldb_private::Address &kext_summary_addr,
- uint32_t image_infos_count,
- OSKextLoadedKextSummary::collection &image_infos);
-
- OSKextLoadedKextSummary m_kernel; // Info about the current kernel image being used
- lldb_private::Address m_kext_summary_header_ptr_addr;
- lldb_private::Address m_kext_summary_header_addr;
- OSKextLoadedKextSummaryHeader m_kext_summary_header;
- OSKextLoadedKextSummary::collection m_kext_summaries;
- mutable lldb_private::Mutex m_mutex;
- lldb::user_id_t m_break_id;
+ uint32_t image_infos_count,
+ KextImageInfo::collection &image_infos);
+
+ static lldb::addr_t
+ SearchForKernelAtSameLoadAddr (lldb_private::Process *process);
+
+ static lldb::addr_t
+ SearchForKernelWithDebugHints (lldb_private::Process *process);
+
+ static lldb::addr_t
+ SearchForKernelNearPC (lldb_private::Process *process);
+
+ static lldb::addr_t
+ SearchForKernelViaExhaustiveSearch (lldb_private::Process *process);
+
+ static lldb_private::UUID
+ CheckForKernelImageAtAddress (lldb::addr_t addr, lldb_private::Process *process);
+
+ lldb::addr_t m_kernel_load_address;
+ KextImageInfo m_kernel; // Info about the current kernel image being used
+
+ lldb_private::Address m_kext_summary_header_ptr_addr;
+ lldb_private::Address m_kext_summary_header_addr;
+ OSKextLoadedKextSummaryHeader m_kext_summary_header;
+ KextImageInfo::collection m_known_kexts;
+ mutable lldb_private::Mutex m_mutex;
+ lldb::user_id_t m_break_id;
private:
DISALLOW_COPY_AND_ASSIGN (DynamicLoaderDarwinKernel);
Modified: lldb/branches/windows/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderMacOSXDYLD.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/windows/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderMacOSXDYLD.cpp?rev=179679&r1=179678&r2=179679&view=diff
==============================================================================
--- lldb/branches/windows/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderMacOSXDYLD.cpp (original)
+++ lldb/branches/windows/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderMacOSXDYLD.cpp Wed Apr 17 03:38:48 2013
@@ -238,7 +238,7 @@ DynamicLoaderMacOSXDYLD::Clear (bool cle
Mutex::Locker locker(m_mutex);
if (m_process->IsAlive() && LLDB_BREAK_ID_IS_VALID(m_break_id))
- m_process->ClearBreakpointSiteByID(m_break_id);
+ m_process->GetTarget().RemoveBreakpointByID (m_break_id);
if (clear_process)
m_process = NULL;
@@ -273,30 +273,33 @@ DynamicLoaderMacOSXDYLD::LocateDYLD()
// mach header for dyld, or it might point to the
// dyld_all_image_infos struct
const addr_t shlib_addr = m_process->GetImageInfoAddress ();
- ByteOrder byte_order = m_process->GetTarget().GetArchitecture().GetByteOrder();
- uint8_t buf[4];
- DataExtractor data (buf, sizeof(buf), byte_order, 4);
- Error error;
- if (m_process->ReadMemory (shlib_addr, buf, 4, error) == 4)
+ if (shlib_addr != LLDB_INVALID_ADDRESS)
{
- uint32_t offset = 0;
- uint32_t magic = data.GetU32 (&offset);
- switch (magic)
- {
- case llvm::MachO::HeaderMagic32:
- case llvm::MachO::HeaderMagic64:
- case llvm::MachO::HeaderMagic32Swapped:
- case llvm::MachO::HeaderMagic64Swapped:
- m_process_image_addr_is_all_images_infos = false;
- return ReadDYLDInfoFromMemoryAndSetNotificationCallback(shlib_addr);
-
- default:
- break;
+ ByteOrder byte_order = m_process->GetTarget().GetArchitecture().GetByteOrder();
+ uint8_t buf[4];
+ DataExtractor data (buf, sizeof(buf), byte_order, 4);
+ Error error;
+ if (m_process->ReadMemory (shlib_addr, buf, 4, error) == 4)
+ {
+ lldb::offset_t offset = 0;
+ uint32_t magic = data.GetU32 (&offset);
+ switch (magic)
+ {
+ case llvm::MachO::HeaderMagic32:
+ case llvm::MachO::HeaderMagic64:
+ case llvm::MachO::HeaderMagic32Swapped:
+ case llvm::MachO::HeaderMagic64Swapped:
+ m_process_image_addr_is_all_images_infos = false;
+ return ReadDYLDInfoFromMemoryAndSetNotificationCallback(shlib_addr);
+
+ default:
+ break;
+ }
}
+ // Maybe it points to the all image infos?
+ m_dyld_all_image_infos_addr = shlib_addr;
+ m_process_image_addr_is_all_images_infos = true;
}
- // Maybe it points to the all image infos?
- m_dyld_all_image_infos_addr = shlib_addr;
- m_process_image_addr_is_all_images_infos = true;
}
if (m_dyld_all_image_infos_addr != LLDB_INVALID_ADDRESS)
@@ -333,13 +336,13 @@ DynamicLoaderMacOSXDYLD::LocateDYLD()
}
ModuleSP
-DynamicLoaderMacOSXDYLD::FindTargetModuleForDYLDImageInfo (const DYLDImageInfo &image_info, bool can_create, bool *did_create_ptr)
+DynamicLoaderMacOSXDYLD::FindTargetModuleForDYLDImageInfo (DYLDImageInfo &image_info, bool can_create, bool *did_create_ptr)
{
if (did_create_ptr)
*did_create_ptr = false;
-
- const ModuleList &target_images = m_process->GetTarget().GetImages();
+ Target &target = m_process->GetTarget();
+ const ModuleList &target_images = target.GetImages();
ModuleSpec module_spec (image_info.file_spec, image_info.GetArchitecture ());
module_spec.GetUUID() = image_info.uuid;
ModuleSP module_sp (target_images.FindFirstModule (module_spec));
@@ -356,16 +359,9 @@ DynamicLoaderMacOSXDYLD::FindTargetModul
{
if (can_create)
{
- module_sp = m_process->GetTarget().GetSharedModule (module_spec);
+ module_sp = target.GetSharedModule (module_spec);
if (!module_sp || module_sp->GetObjectFile() == NULL)
- {
- const bool add_image_to_target = true;
- const bool load_image_sections_in_target = false;
- module_sp = m_process->ReadModuleFromMemory (image_info.file_spec,
- image_info.address,
- add_image_to_target,
- load_image_sections_in_target);
- }
+ module_sp = m_process->ReadModuleFromMemory (image_info.file_spec, image_info.address);
if (did_create_ptr)
*did_create_ptr = (bool) module_sp;
@@ -399,12 +395,14 @@ DynamicLoaderMacOSXDYLD::ReadDYLDInfoFro
}
}
+ Target &target = m_process->GetTarget();
+
if (m_dyld_all_image_infos_addr == LLDB_INVALID_ADDRESS && dyld_module_sp.get())
{
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(&m_process->GetTarget());
+ m_dyld_all_image_infos_addr = symbol->GetAddress().GetLoadAddress(&target);
}
// Update all image infos
@@ -417,13 +415,12 @@ DynamicLoaderMacOSXDYLD::ReadDYLDInfoFro
/// unique!
if (dyld_module_sp)
{
- if (m_process->GetTarget().GetImages().AppendIfNeeded (dyld_module_sp))
- UpdateImageLoadAddress(dyld_module_sp.get(), m_dyld);
+ target.GetImages().AppendIfNeeded (dyld_module_sp);
// At this point we should have read in dyld's module, and so we should set breakpoints in it:
ModuleList modules;
modules.Append(dyld_module_sp);
- m_process->GetTarget().ModulesDidLoad(modules);
+ target.ModulesDidLoad(modules);
}
return true;
}
@@ -437,40 +434,6 @@ DynamicLoaderMacOSXDYLD::NeedToLocateDYL
return m_dyld_all_image_infos_addr == LLDB_INVALID_ADDRESS;
}
-bool
-DynamicLoaderMacOSXDYLD::UpdateCommPageLoadAddress(Module *module)
-{
- bool changed = false;
- if (module)
- {
- ObjectFile *image_object_file = module->GetObjectFile();
- if (image_object_file)
- {
- SectionList *section_list = image_object_file->GetSectionList ();
- if (section_list)
- {
- uint32_t num_sections = section_list->GetSize();
- for (uint32_t i=0; i<num_sections; ++i)
- {
- SectionSP section_sp (section_list->GetSectionAtIndex (i));
- if (section_sp)
- {
- const addr_t new_section_load_addr = section_sp->GetFileAddress ();
- const addr_t old_section_load_addr = m_process->GetTarget().GetSectionLoadList().GetSectionLoadAddress (section_sp);
- if (old_section_load_addr == LLDB_INVALID_ADDRESS ||
- old_section_load_addr != new_section_load_addr)
- {
- if (m_process->GetTarget().GetSectionLoadList().SetSectionLoadAddress (section_sp, section_sp->GetFileAddress ()))
- changed = true;
- }
- }
- }
- }
- }
- }
- return changed;
-}
-
//----------------------------------------------------------------------
// Update the load addresses for all segments in MODULE using the
// updated INFO that is passed in.
@@ -490,8 +453,8 @@ DynamicLoaderMacOSXDYLD::UpdateImageLoad
std::vector<uint32_t> inaccessible_segment_indexes;
// We now know the slide amount, so go through all sections
// and update the load addresses with the correct values.
- uint32_t num_segments = info.segments.size();
- for (uint32_t i=0; i<num_segments; ++i)
+ const size_t num_segments = info.segments.size();
+ for (size_t i=0; i<num_segments; ++i)
{
// Only load a segment if it has protections. Things like
// __PAGEZERO don't have any protections, and they shouldn't
@@ -566,6 +529,14 @@ DynamicLoaderMacOSXDYLD::UpdateImageLoad
}
}
}
+ // We might have an in memory image that was loaded as soon as it was created
+ if (info.load_stop_id == m_process->GetStopID())
+ changed = true;
+ else if (changed)
+ {
+ // Update the stop ID when this library was updated
+ info.load_stop_id = m_process->GetStopID();
+ }
return changed;
}
@@ -585,8 +556,8 @@ DynamicLoaderMacOSXDYLD::UnloadImageLoad
SectionList *section_list = image_object_file->GetSectionList ();
if (section_list)
{
- uint32_t num_segments = info.segments.size();
- for (uint32_t i=0; i<num_segments; ++i)
+ const size_t num_segments = info.segments.size();
+ for (size_t i=0; i<num_segments; ++i)
{
SectionSP section_sp(section_list->FindSectionByName(info.segments[i].name));
if (section_sp)
@@ -715,7 +686,7 @@ DynamicLoaderMacOSXDYLD::ReadAllImageInf
uint8_t buf[256];
DataExtractor data (buf, sizeof(buf), byte_order, addr_size);
- uint32_t offset = 0;
+ lldb::offset_t offset = 0;
const size_t count_v2 = sizeof (uint32_t) + // version
sizeof (uint32_t) + // infoArrayCount
@@ -738,9 +709,15 @@ DynamicLoaderMacOSXDYLD::ReadAllImageInf
addr_size + // errorClientOfDylibPath
addr_size + // errorTargetDylibPath
addr_size; // errorSymbol
- assert (sizeof (buf) >= count_v11);
+ const size_t count_v13 = count_v11 +
+ addr_size + // sharedCacheSlide
+#ifdef _WIN32
+ 16;
+#else
+ sizeof (uuid_t); // sharedCacheUUID
+#endif
+ assert (sizeof (buf) >= count_v13);
- int count;
Error error;
if (m_process->ReadMemory (m_dyld_all_image_infos_addr, buf, 4, error) == 4)
{
@@ -767,10 +744,7 @@ DynamicLoaderMacOSXDYLD::ReadAllImageInf
return false;
}
- if (m_dyld_all_image_infos.version >= 11)
- count = count_v11;
- else
- count = count_v2;
+ const size_t count = (m_dyld_all_image_infos.version >= 11) ? count_v11 : count_v2;
const size_t bytes_read = m_process->ReadMemory (m_dyld_all_image_infos_addr, buf, count, error);
if (bytes_read == count)
@@ -821,7 +795,7 @@ bool
DynamicLoaderMacOSXDYLD::AddModulesUsingImageInfosAddress (lldb::addr_t image_infos_addr, uint32_t image_infos_count)
{
DYLDImageInfo::collection image_infos;
- LogSP log(lldb_private::GetLogIfAnyCategoriesSet (LIBLLDB_LOG_DYNAMIC_LOADER));
+ Log *log(lldb_private::GetLogIfAnyCategoriesSet (LIBLLDB_LOG_DYNAMIC_LOADER));
if (log)
log->Printf ("Adding %d modules.\n", image_infos_count);
@@ -846,14 +820,16 @@ DynamicLoaderMacOSXDYLD::AddModulesUsing
{
// Now add these images to the main list.
ModuleList loaded_module_list;
- LogSP log(lldb_private::GetLogIfAnyCategoriesSet (LIBLLDB_LOG_DYNAMIC_LOADER));
+ Log *log(lldb_private::GetLogIfAnyCategoriesSet (LIBLLDB_LOG_DYNAMIC_LOADER));
+ Target &target = m_process->GetTarget();
+ ModuleList& target_images = target.GetImages();
for (uint32_t idx = 0; idx < image_infos.size(); ++idx)
{
if (log)
{
log->Printf ("Adding new image at address=0x%16.16" PRIx64 ".", image_infos[idx].address);
- image_infos[idx].PutToLog (log.get());
+ image_infos[idx].PutToLog (log);
}
m_dyld_image_infos.push_back(image_infos[idx]);
@@ -875,26 +851,31 @@ DynamicLoaderMacOSXDYLD::AddModulesUsing
Section *commpage_section = sections->FindSectionByName(commpage_dbstr).get();
if (commpage_section)
{
- const ModuleList& target_images = m_process->GetTarget().GetImages();
ModuleSpec module_spec (objfile->GetFileSpec(), image_infos[idx].GetArchitecture ());
module_spec.GetObjectName() = commpage_dbstr;
ModuleSP commpage_image_module_sp(target_images.FindFirstModule (module_spec));
if (!commpage_image_module_sp)
{
- module_spec.SetObjectOffset (objfile->GetOffset() + commpage_section->GetFileOffset());
- commpage_image_module_sp = m_process->GetTarget().GetSharedModule (module_spec);
+ module_spec.SetObjectOffset (objfile->GetFileOffset() + commpage_section->GetFileOffset());
+ commpage_image_module_sp = target.GetSharedModule (module_spec);
if (!commpage_image_module_sp || commpage_image_module_sp->GetObjectFile() == NULL)
{
- const bool add_image_to_target = true;
- const bool load_image_sections_in_target = false;
commpage_image_module_sp = m_process->ReadModuleFromMemory (image_infos[idx].file_spec,
- image_infos[idx].address,
- add_image_to_target,
- load_image_sections_in_target);
+ image_infos[idx].address);
+ // Always load a memory image right away in the target in case
+ // we end up trying to read the symbol table from memory... The
+ // __LINKEDIT will need to be mapped so we can figure out where
+ // the symbol table bits are...
+ bool changed = false;
+ UpdateImageLoadAddress (commpage_image_module_sp.get(), image_infos[idx]);
+ target.GetImages().Append(commpage_image_module_sp);
+ if (changed)
+ {
+ image_infos[idx].load_stop_id = m_process->GetStopID();
+ loaded_module_list.AppendIfNeeded (commpage_image_module_sp);
+ }
}
}
- if (commpage_image_module_sp)
- UpdateCommPageLoadAddress (commpage_image_module_sp.get());
}
}
}
@@ -906,6 +887,7 @@ DynamicLoaderMacOSXDYLD::AddModulesUsing
// shared libraries each time.
if (UpdateImageLoadAddress (image_module_sp.get(), image_infos[idx]))
{
+ target_images.AppendIfNeeded(image_module_sp);
loaded_module_list.AppendIfNeeded (image_module_sp);
}
}
@@ -942,7 +924,7 @@ bool
DynamicLoaderMacOSXDYLD::RemoveModulesUsingImageInfosAddress (lldb::addr_t image_infos_addr, uint32_t image_infos_count)
{
DYLDImageInfo::collection image_infos;
- LogSP log(lldb_private::GetLogIfAnyCategoriesSet (LIBLLDB_LOG_DYNAMIC_LOADER));
+ Log *log(lldb_private::GetLogIfAnyCategoriesSet (LIBLLDB_LOG_DYNAMIC_LOADER));
Mutex::Locker locker(m_mutex);
if (m_process->GetStopID() == m_dyld_image_infos_stop_id)
@@ -965,7 +947,7 @@ DynamicLoaderMacOSXDYLD::RemoveModulesUs
if (log)
{
log->Printf ("Removing module at address=0x%16.16" PRIx64 ".", image_infos[idx].address);
- image_infos[idx].PutToLog (log.get());
+ image_infos[idx].PutToLog (log);
}
// Remove this image_infos from the m_all_image_infos. We do the comparision by address
@@ -998,7 +980,7 @@ DynamicLoaderMacOSXDYLD::RemoveModulesUs
if (log)
{
log->Printf ("Could not find module for unloading info entry:");
- image_infos[idx].PutToLog(log.get());
+ image_infos[idx].PutToLog(log);
}
}
@@ -1014,7 +996,7 @@ DynamicLoaderMacOSXDYLD::RemoveModulesUs
if (log)
{
log->Printf ("Could not find image_info entry for unloading image:");
- image_infos[idx].PutToLog(log.get());
+ image_infos[idx].PutToLog(log);
}
}
}
@@ -1049,7 +1031,7 @@ DynamicLoaderMacOSXDYLD::ReadImageInfos
error);
if (bytes_read == count)
{
- uint32_t info_data_offset = 0;
+ lldb::offset_t info_data_offset = 0;
DataExtractor info_data_ref(info_data.GetBytes(), info_data.GetByteSize(), endian, addr_size);
for (int i = 0; i < image_infos.size() && info_data_ref.ValidOffset(info_data_offset); i++)
{
@@ -1084,7 +1066,7 @@ DynamicLoaderMacOSXDYLD::ReadImageInfos
bool
DynamicLoaderMacOSXDYLD::InitializeFromAllImageInfos ()
{
- LogSP log(lldb_private::GetLogIfAnyCategoriesSet (LIBLLDB_LOG_DYNAMIC_LOADER));
+ Log *log(lldb_private::GetLogIfAnyCategoriesSet (LIBLLDB_LOG_DYNAMIC_LOADER));
Mutex::Locker locker(m_mutex);
if (m_process->GetStopID() == m_dyld_image_infos_stop_id
@@ -1167,7 +1149,7 @@ DynamicLoaderMacOSXDYLD::ReadMachHeader
error);
if (bytes_read == sizeof(llvm::MachO::mach_header))
{
- uint32_t offset = 0;
+ lldb::offset_t offset = 0;
::memset (header, 0, sizeof(llvm::MachO::mach_header));
// Get the magic byte unswapped so we can figure out what we are dealing with
@@ -1229,7 +1211,7 @@ DynamicLoaderMacOSXDYLD::ReadMachHeader
uint32_t
DynamicLoaderMacOSXDYLD::ParseLoadCommands (const DataExtractor& data, DYLDImageInfo& dylib_info, FileSpec *lc_id_dylinker)
{
- uint32_t offset = 0;
+ lldb::offset_t offset = 0;
uint32_t cmd_idx;
Segment segment;
dylib_info.Clear (true);
@@ -1242,7 +1224,7 @@ DynamicLoaderMacOSXDYLD::ParseLoadComman
if (data.ValidOffsetForDataOfSize (offset, sizeof(llvm::MachO::load_command)))
{
llvm::MachO::load_command load_cmd;
- uint32_t load_cmd_offset = offset;
+ lldb::offset_t load_cmd_offset = offset;
load_cmd.cmd = data.GetU32 (&offset);
load_cmd.cmdsize = data.GetU32 (&offset);
switch (load_cmd.cmd)
@@ -1276,7 +1258,7 @@ DynamicLoaderMacOSXDYLD::ParseLoadComman
case llvm::MachO::LoadCommandDynamicLinkerIdent:
if (lc_id_dylinker)
{
- uint32_t name_offset = load_cmd_offset + data.GetU32 (&offset);
+ const lldb::offset_t name_offset = load_cmd_offset + data.GetU32 (&offset);
const char *path = data.PeekCStr (name_offset);
lc_id_dylinker->SetFile (path, true);
}
@@ -1329,7 +1311,6 @@ DynamicLoaderMacOSXDYLD::UpdateImageInfo
bool update_executable)
{
uint32_t exe_idx = UINT32_MAX;
- LogSP log(lldb_private::GetLogIfAnyCategoriesSet (LIBLLDB_LOG_DYNAMIC_LOADER));
// Read any UUID values that we can get
for (uint32_t i = 0; i < infos_count; i++)
{
@@ -1347,32 +1328,18 @@ DynamicLoaderMacOSXDYLD::UpdateImageInfo
}
}
+ Target &target = m_process->GetTarget();
+
if (exe_idx < image_infos.size())
{
const bool can_create = true;
ModuleSP exe_module_sp (FindTargetModuleForDYLDImageInfo (image_infos[exe_idx], can_create, NULL));
- if (!exe_module_sp)
- {
- ArchSpec exe_arch_spec (image_infos[exe_idx].GetArchitecture ());
- ModuleSpec module_spec (image_infos[exe_idx].file_spec,
- image_infos[exe_idx].GetArchitecture ());
- module_spec.GetUUID() = image_infos[exe_idx].uuid;
- exe_module_sp = m_process->GetTarget().GetSharedModule (module_spec);
- if (!exe_module_sp || exe_module_sp->GetObjectFile() == NULL)
- {
- const bool add_image_to_target = true;
- const bool load_image_sections_in_target = false;
- exe_module_sp = m_process->ReadModuleFromMemory (image_infos[exe_idx].file_spec,
- image_infos[exe_idx].address,
- add_image_to_target,
- load_image_sections_in_target);
- }
- }
-
if (exe_module_sp)
{
- if (exe_module_sp.get() != m_process->GetTarget().GetExecutableModulePointer())
+ UpdateImageLoadAddress (exe_module_sp.get(), image_infos[exe_idx]);
+
+ if (exe_module_sp.get() != target.GetExecutableModulePointer())
{
// Don't load dependent images since we are in dyld where we will know
// and find out about all images that are loaded
@@ -1569,6 +1536,7 @@ DynamicLoaderMacOSXDYLD::SetNotification
{
Breakpoint *dyld_break = m_process->GetTarget().CreateBreakpoint (so_addr, true).get();
dyld_break->SetCallback (DynamicLoaderMacOSXDYLD::NotifyBreakpointHit, this, true);
+ dyld_break->SetBreakpointKind ("shared-library-event");
m_break_id = dyld_break->GetID();
}
}
@@ -1630,7 +1598,7 @@ DynamicLoaderMacOSXDYLD::GetStepThroughT
StackFrame *current_frame = thread.GetStackFrameAtIndex(0).get();
const SymbolContext ¤t_context = current_frame->GetSymbolContext(eSymbolContextSymbol);
Symbol *current_symbol = current_context.symbol;
- LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP));
+ Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP));
if (current_symbol != NULL)
{
Modified: lldb/branches/windows/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderMacOSXDYLD.h
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/windows/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderMacOSXDYLD.h?rev=179679&r1=179678&r2=179679&view=diff
==============================================================================
--- lldb/branches/windows/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderMacOSXDYLD.h (original)
+++ lldb/branches/windows/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderMacOSXDYLD.h Wed Apr 17 03:38:48 2013
@@ -178,6 +178,7 @@ protected:
lldb_private::UUID uuid; // UUID for this dylib if it has one, else all zeros
llvm::MachO::mach_header header; // The mach header for this image
std::vector<Segment> segments; // All segment vmaddr and vmsize pairs for this executable (from memory of inferior)
+ uint32_t load_stop_id; // The process stop ID that the sections for this image were loadeded
DYLDImageInfo() :
address(LLDB_INVALID_ADDRESS),
@@ -186,7 +187,8 @@ protected:
file_spec(),
uuid(),
header(),
- segments()
+ segments(),
+ load_stop_id(0)
{
}
@@ -203,6 +205,7 @@ protected:
}
uuid.Clear();
segments.clear();
+ load_stop_id = 0;
}
bool
@@ -316,7 +319,7 @@ protected:
DYLDImageInfo& info);
lldb::ModuleSP
- FindTargetModuleForDYLDImageInfo (const DYLDImageInfo &image_info,
+ FindTargetModuleForDYLDImageInfo (DYLDImageInfo &image_info,
bool can_create,
bool *did_create_ptr);
@@ -358,9 +361,6 @@ protected:
bool update_executable);
bool
- UpdateCommPageLoadAddress (lldb_private::Module *module);
-
- bool
ReadImageInfos (lldb::addr_t image_infos_addr,
uint32_t image_infos_count,
DYLDImageInfo::collection &image_infos);
Modified: lldb/branches/windows/source/Plugins/DynamicLoader/POSIX-DYLD/AuxVector.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/windows/source/Plugins/DynamicLoader/POSIX-DYLD/AuxVector.cpp?rev=179679&r1=179678&r2=179679&view=diff
==============================================================================
--- lldb/branches/windows/source/Plugins/DynamicLoader/POSIX-DYLD/AuxVector.cpp (original)
+++ lldb/branches/windows/source/Plugins/DynamicLoader/POSIX-DYLD/AuxVector.cpp Wed Apr 17 03:38:48 2013
@@ -26,21 +26,25 @@ using namespace lldb_private;
static bool
GetMaxU64(DataExtractor &data,
- uint32_t *offset, uint64_t *value, unsigned int byte_size)
-{
- uint32_t saved_offset = *offset;
- *value = data.GetMaxU64(offset, byte_size);
- return *offset != saved_offset;
+ lldb::offset_t *offset_ptr,
+ uint64_t *value,
+ unsigned int byte_size)
+{
+ lldb::offset_t saved_offset = *offset_ptr;
+ *value = data.GetMaxU64(offset_ptr, byte_size);
+ return *offset_ptr != saved_offset;
}
static bool
-ParseAuxvEntry(DataExtractor &data, AuxVector::Entry &entry,
- uint32_t *offset, unsigned int byte_size)
+ParseAuxvEntry(DataExtractor &data,
+ AuxVector::Entry &entry,
+ lldb::offset_t *offset_ptr,
+ unsigned int byte_size)
{
- if (!GetMaxU64(data, offset, &entry.type, byte_size))
+ if (!GetMaxU64(data, offset_ptr, &entry.type, byte_size))
return false;
- if (!GetMaxU64(data, offset, &entry.value, byte_size))
+ if (!GetMaxU64(data, offset_ptr, &entry.value, byte_size))
return false;
return true;
@@ -57,7 +61,7 @@ void
AuxVector::ParseAuxv(DataExtractor &data)
{
const unsigned int byte_size = m_process->GetAddressByteSize();
- uint32_t offset = 0;
+ lldb::offset_t offset = 0;
for (;;)
{
@@ -80,7 +84,7 @@ AuxVector::AuxVector(Process *process)
: m_process(process)
{
DataExtractor data;
- LogSP log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_DYNAMIC_LOADER));
+ Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_DYNAMIC_LOADER));
data.SetData(GetAuxvData());
data.SetByteOrder(m_process->GetByteOrder());
@@ -105,7 +109,7 @@ AuxVector::FindEntry(EntryType type) con
}
void
-AuxVector::DumpToLog(LogSP log) const
+AuxVector::DumpToLog(Log *log) const
{
if (!log)
return;
Modified: lldb/branches/windows/source/Plugins/DynamicLoader/POSIX-DYLD/AuxVector.h
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/windows/source/Plugins/DynamicLoader/POSIX-DYLD/AuxVector.h?rev=179679&r1=179678&r2=179679&view=diff
==============================================================================
--- lldb/branches/windows/source/Plugins/DynamicLoader/POSIX-DYLD/AuxVector.h (original)
+++ lldb/branches/windows/source/Plugins/DynamicLoader/POSIX-DYLD/AuxVector.h Wed Apr 17 03:38:48 2013
@@ -81,7 +81,7 @@ public:
GetEntryName(EntryType type);
void
- DumpToLog(lldb::LogSP log) const;
+ DumpToLog(lldb_private::Log *log) const;
private:
lldb_private::Process *m_process;
Modified: lldb/branches/windows/source/Plugins/DynamicLoader/POSIX-DYLD/DYLDRendezvous.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/windows/source/Plugins/DynamicLoader/POSIX-DYLD/DYLDRendezvous.cpp?rev=179679&r1=179678&r2=179679&view=diff
==============================================================================
--- lldb/branches/windows/source/Plugins/DynamicLoader/POSIX-DYLD/DYLDRendezvous.cpp (original)
+++ lldb/branches/windows/source/Plugins/DynamicLoader/POSIX-DYLD/DYLDRendezvous.cpp Wed Apr 17 03:38:48 2013
@@ -295,7 +295,7 @@ DYLDRendezvous::ReadSOEntryFromMemory(ll
}
void
-DYLDRendezvous::DumpToLog(LogSP log) const
+DYLDRendezvous::DumpToLog(Log *log) const
{
int state = GetState();
@@ -304,7 +304,7 @@ DYLDRendezvous::DumpToLog(LogSP log) con
log->PutCString("DYLDRendezvous:");
log->Printf(" Address: %" PRIx64, GetRendezvousAddress());
- log->Printf(" Version: %d", GetVersion());
+ log->Printf(" Version: %" PRIu64, GetVersion());
log->Printf(" Link : %" PRIx64, GetLinkMapAddress());
log->Printf(" Break : %" PRIx64, GetBreakAddress());
log->Printf(" LDBase : %" PRIx64, GetLDBase());
Modified: lldb/branches/windows/source/Plugins/DynamicLoader/POSIX-DYLD/DYLDRendezvous.h
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/windows/source/Plugins/DynamicLoader/POSIX-DYLD/DYLDRendezvous.h?rev=179679&r1=179678&r2=179679&view=diff
==============================================================================
--- lldb/branches/windows/source/Plugins/DynamicLoader/POSIX-DYLD/DYLDRendezvous.h (original)
+++ lldb/branches/windows/source/Plugins/DynamicLoader/POSIX-DYLD/DYLDRendezvous.h Wed Apr 17 03:38:48 2013
@@ -73,7 +73,7 @@ public:
GetRendezvousAddress() const { return m_rendezvous_addr; }
/// @returns the version of the rendezvous protocol being used.
- int
+ uint64_t
GetVersion() const { return m_current.version; }
/// @returns address in the inferiors address space containing the linked
@@ -92,7 +92,7 @@ public:
GetBreakAddress() const { return m_current.brk; }
/// Returns the current state of the rendezvous structure.
- int
+ uint64_t
GetState() const { return m_current.state; }
/// @returns the base address of the runtime linker in the inferiors address
@@ -111,7 +111,7 @@ public:
ModulesDidUnload() const { return !m_removed_soentries.empty(); }
void
- DumpToLog(lldb::LogSP log) const;
+ DumpToLog(lldb_private::Log *log) const;
/// @brief Constants describing the state of the rendezvous.
///
Modified: lldb/branches/windows/source/Plugins/DynamicLoader/POSIX-DYLD/DynamicLoaderPOSIXDYLD.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/windows/source/Plugins/DynamicLoader/POSIX-DYLD/DynamicLoaderPOSIXDYLD.cpp?rev=179679&r1=179678&r2=179679&view=diff
==============================================================================
--- lldb/branches/windows/source/Plugins/DynamicLoader/POSIX-DYLD/DynamicLoaderPOSIXDYLD.cpp (original)
+++ lldb/branches/windows/source/Plugins/DynamicLoader/POSIX-DYLD/DynamicLoaderPOSIXDYLD.cpp Wed Apr 17 03:38:48 2013
@@ -114,7 +114,7 @@ DynamicLoaderPOSIXDYLD::DidAttach()
m_auxv.reset(new AuxVector(m_process));
- executable = m_process->GetTarget().GetExecutableModule();
+ executable = GetTargetExecutable();
load_offset = ComputeLoadOffset();
if (executable.get() && load_offset != LLDB_INVALID_ADDRESS)
@@ -135,7 +135,7 @@ DynamicLoaderPOSIXDYLD::DidLaunch()
m_auxv.reset(new AuxVector(m_process));
- executable = m_process->GetTarget().GetExecutableModule();
+ executable = GetTargetExecutable();
load_offset = ComputeLoadOffset();
if (executable.get() && load_offset != LLDB_INVALID_ADDRESS)
@@ -148,6 +148,46 @@ DynamicLoaderPOSIXDYLD::DidLaunch()
}
}
+ModuleSP
+DynamicLoaderPOSIXDYLD::GetTargetExecutable()
+{
+ Target &target = m_process->GetTarget();
+ ModuleSP executable = target.GetExecutableModule();
+
+ if (executable.get())
+ {
+ if (executable->GetFileSpec().Exists())
+ {
+ ModuleSpec module_spec (executable->GetFileSpec(), executable->GetArchitecture());
+ ModuleSP module_sp (new Module (module_spec));
+
+ // Check if the executable has changed and set it to the target executable if they differ.
+ if (module_sp.get() && module_sp->GetUUID().IsValid() && executable->GetUUID().IsValid())
+ {
+ if (module_sp->GetUUID() != executable->GetUUID())
+ executable.reset();
+ }
+ else if (executable->FileHasChanged())
+ {
+ executable.reset();
+ }
+
+ if (!executable.get())
+ {
+ executable = target.GetSharedModule(module_spec);
+ if (executable.get() != target.GetExecutableModulePointer())
+ {
+ // Don't load dependent images since we are in dyld where we will know
+ // and find out about all images that are loaded
+ const bool get_dependent_images = false;
+ target.SetExecutableModule(executable, get_dependent_images);
+ }
+ }
+ }
+ }
+ return executable;
+}
+
Error
DynamicLoaderPOSIXDYLD::ExecutePluginCommand(Args &command, Stream *strm)
{
@@ -202,6 +242,7 @@ DynamicLoaderPOSIXDYLD::ProbeEntry()
entry_break = m_process->GetTarget().CreateBreakpoint(entry, true).get();
entry_break->SetCallback(EntryBreakpointHit, this, true);
+ entry_break->SetBreakpointKind("shared-library-event");
}
// The runtime linker has run and initialized the rendezvous structure once the
@@ -233,6 +274,7 @@ DynamicLoaderPOSIXDYLD::SetRendezvousBre
break_addr = m_rendezvous.GetBreakAddress();
dyld_break = m_process->GetTarget().CreateBreakpoint(break_addr, true).get();
dyld_break->SetCallback(RendezvousBreakpointHit, this, true);
+ dyld_break->SetBreakpointKind ("shared-library-event");
}
bool
Modified: lldb/branches/windows/source/Plugins/DynamicLoader/POSIX-DYLD/DynamicLoaderPOSIXDYLD.h
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/windows/source/Plugins/DynamicLoader/POSIX-DYLD/DynamicLoaderPOSIXDYLD.h?rev=179679&r1=179678&r2=179679&view=diff
==============================================================================
--- lldb/branches/windows/source/Plugins/DynamicLoader/POSIX-DYLD/DynamicLoaderPOSIXDYLD.h (original)
+++ lldb/branches/windows/source/Plugins/DynamicLoader/POSIX-DYLD/DynamicLoaderPOSIXDYLD.h Wed Apr 17 03:38:48 2013
@@ -158,6 +158,11 @@ protected:
lldb::addr_t
GetEntryPoint();
+ /// Checks to see if the target module has changed, updates the target
+ /// accordingly and returns the target executable module.
+ lldb::ModuleSP
+ GetTargetExecutable();
+
private:
DISALLOW_COPY_AND_ASSIGN(DynamicLoaderPOSIXDYLD);
};
Modified: lldb/branches/windows/source/Plugins/DynamicLoader/Static/DynamicLoaderStatic.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/windows/source/Plugins/DynamicLoader/Static/DynamicLoaderStatic.cpp?rev=179679&r1=179678&r2=179679&view=diff
==============================================================================
--- lldb/branches/windows/source/Plugins/DynamicLoader/Static/DynamicLoaderStatic.cpp (original)
+++ lldb/branches/windows/source/Plugins/DynamicLoader/Static/DynamicLoaderStatic.cpp Wed Apr 17 03:38:48 2013
@@ -99,6 +99,9 @@ DynamicLoaderStatic::LoadAllImagesAtFile
ModuleList loaded_module_list;
+ // Disable JIT for static dynamic loader targets
+ m_process->SetCanJIT(false);
+
Mutex::Locker mutex_locker(module_list.GetMutex());
const size_t num_modules = module_list.GetSize();
Modified: lldb/branches/windows/source/Plugins/LanguageRuntime/CPlusPlus/ItaniumABI/ItaniumABILanguageRuntime.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/windows/source/Plugins/LanguageRuntime/CPlusPlus/ItaniumABI/ItaniumABILanguageRuntime.cpp?rev=179679&r1=179678&r2=179679&view=diff
==============================================================================
--- lldb/branches/windows/source/Plugins/LanguageRuntime/CPlusPlus/ItaniumABI/ItaniumABILanguageRuntime.cpp (original)
+++ lldb/branches/windows/source/Plugins/LanguageRuntime/CPlusPlus/ItaniumABI/ItaniumABILanguageRuntime.cpp Wed Apr 17 03:38:48 2013
@@ -59,6 +59,8 @@ ItaniumABILanguageRuntime::GetDynamicTyp
// start of the value object which holds the dynamic type.
//
+ class_type_or_name.Clear();
+
// Only a pointer or reference type can have a different dynamic and static type:
if (CouldHaveDynamicValue (in_value))
{
@@ -88,10 +90,10 @@ ItaniumABILanguageRuntime::GetDynamicTyp
return false;
}
- uint32_t offset_ptr = 0;
- lldb::addr_t vtable_address_point = data.GetAddress (&offset_ptr);
+ lldb::offset_t offset = 0;
+ lldb::addr_t vtable_address_point = data.GetAddress (&offset);
- if (offset_ptr == 0)
+ if (offset == 0)
return false;
// Now find the symbol that contains this address:
@@ -109,7 +111,7 @@ ItaniumABILanguageRuntime::GetDynamicTyp
const char *name = symbol->GetMangled().GetDemangledName().AsCString();
if (strstr(name, vtable_demangled_prefix) == name)
{
- LogSP log (lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_OBJECT));
+ Log *log (lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_OBJECT));
if (log)
log->Printf ("0x%16.16" PRIx64 ": static-type = '%s' has vtable symbol '%s'\n",
original_ptr,
@@ -253,8 +255,8 @@ ItaniumABILanguageRuntime::GetDynamicTyp
return false;
}
- offset_ptr = 0;
- int64_t offset_to_top = data.GetMaxS64(&offset_ptr, process->GetAddressByteSize());
+ offset = 0;
+ int64_t offset_to_top = data.GetMaxS64(&offset, process->GetAddressByteSize());
// So the dynamic type is a value that starts at offset_to_top
// above the original address.
@@ -271,7 +273,7 @@ ItaniumABILanguageRuntime::GetDynamicTyp
}
}
- return false;
+ return class_type_or_name.IsEmpty() == false;
}
bool
@@ -336,10 +338,6 @@ ItaniumABILanguageRuntime::GetPluginVers
return 1;
}
-static const char *exception_names[] = { "__cxa_begin_catch", "__cxa_throw", "__cxa_rethrow", "__cxa_allocate_exception"};
-static const int num_throw_names = 3;
-static const int num_expression_throw_names = 1;
-
BreakpointResolverSP
ItaniumABILanguageRuntime::CreateExceptionResolver (Breakpoint *bkpt, bool catch_bp, bool throw_bp)
{
@@ -349,49 +347,70 @@ ItaniumABILanguageRuntime::CreateExcepti
BreakpointResolverSP
ItaniumABILanguageRuntime::CreateExceptionResolver (Breakpoint *bkpt, bool catch_bp, bool throw_bp, bool for_expressions)
{
- BreakpointResolverSP resolver_sp;
- static const int total_expressions = sizeof (exception_names)/sizeof (char *);
-
// One complication here is that most users DON'T want to stop at __cxa_allocate_expression, but until we can do
// anything better with predicting unwinding the expression parser does. So we have two forms of the exception
// breakpoints, one for expressions that leaves out __cxa_allocate_exception, and one that includes it.
// The SetExceptionBreakpoints does the latter, the CreateExceptionBreakpoint in the runtime the former.
+ static const char *g_catch_name = "__cxa_begin_catch";
+ static const char *g_throw_name1 = "__cxa_throw";
+ static const char *g_throw_name2 = "__cxa_rethrow";
+ static const char *g_exception_throw_name = "__cxa_allocate_exception";
+ std::vector<const char *> exception_names;
+ exception_names.reserve(4);
+ if (catch_bp)
+ exception_names.push_back(g_catch_name);
+
+ if (throw_bp)
+ {
+ exception_names.push_back(g_throw_name1);
+ exception_names.push_back(g_throw_name2);
+ }
+
+ if (for_expressions)
+ exception_names.push_back(g_exception_throw_name);
- uint32_t num_expressions;
- if (catch_bp && throw_bp)
+ BreakpointResolverSP resolver_sp (new BreakpointResolverName (bkpt,
+ exception_names.data(),
+ exception_names.size(),
+ eFunctionNameTypeBase,
+ eLazyBoolNo));
+
+ return resolver_sp;
+}
+
+
+
+lldb::SearchFilterSP
+ItaniumABILanguageRuntime::CreateExceptionSearchFilter ()
+{
+ Target &target = m_process->GetTarget();
+
+ if (target.GetArchitecture().GetTriple().getVendor() == llvm::Triple::Apple)
{
- if (for_expressions)
- num_expressions = total_expressions;
- else
- num_expressions = total_expressions - num_expression_throw_names;
-
- resolver_sp.reset (new BreakpointResolverName (bkpt,
- exception_names,
- num_expressions,
- eFunctionNameTypeBase,
- eLazyBoolNo));
+ // Limit the number of modules that are searched for these breakpoints for
+ // Apple binaries.
+ FileSpecList filter_modules;
+ filter_modules.Append(FileSpec("libc++abi.dylib", false));
+ filter_modules.Append(FileSpec("libSystem.B.dylib", false));
+ return target.GetSearchFilterForModuleList(&filter_modules);
}
- else if (throw_bp)
+ else
{
- if (for_expressions)
- num_expressions = num_throw_names - num_expression_throw_names;
- else
- num_expressions = num_throw_names;
-
- resolver_sp.reset (new BreakpointResolverName (bkpt,
- exception_names + 1,
- num_expressions,
- eFunctionNameTypeBase,
- eLazyBoolNo));
+ return LanguageRuntime::CreateExceptionSearchFilter();
}
- else if (catch_bp)
- resolver_sp.reset (new BreakpointResolverName (bkpt,
- exception_names,
- total_expressions - num_throw_names,
- eFunctionNameTypeBase,
- eLazyBoolNo));
+}
- return resolver_sp;
+lldb::BreakpointSP
+ItaniumABILanguageRuntime::CreateExceptionBreakpoint (bool catch_bp,
+ bool throw_bp,
+ bool for_expressions,
+ bool is_internal)
+{
+ Target &target = m_process->GetTarget();
+ FileSpecList filter_modules;
+ BreakpointResolverSP exception_resolver_sp = CreateExceptionResolver (NULL, catch_bp, throw_bp, for_expressions);
+ SearchFilterSP filter_sp (CreateExceptionSearchFilter ());
+ return target.CreateBreakpoint (filter_sp, exception_resolver_sp, is_internal);
}
void
@@ -408,17 +427,16 @@ ItaniumABILanguageRuntime::SetExceptionB
// For the exception breakpoints set by the Expression parser, we'll be a little more aggressive and
// stop at exception allocation as well.
- if (!m_cxx_exception_bp_sp)
+ if (m_cxx_exception_bp_sp)
{
- Target &target = m_process->GetTarget();
-
- BreakpointResolverSP exception_resolver_sp = CreateExceptionResolver (NULL, catch_bp, throw_bp, for_expressions);
- SearchFilterSP filter_sp = target.GetSearchFilterForModule(NULL);
-
- m_cxx_exception_bp_sp = target.CreateBreakpoint (filter_sp, exception_resolver_sp, is_internal);
+ m_cxx_exception_bp_sp->SetEnabled (true);
}
else
- m_cxx_exception_bp_sp->SetEnabled (true);
+ {
+ m_cxx_exception_bp_sp = CreateExceptionBreakpoint (catch_bp, throw_bp, for_expressions, is_internal);
+ if (m_cxx_exception_bp_sp)
+ m_cxx_exception_bp_sp->SetBreakpointKind("c++ exception");
+ }
}
@@ -428,7 +446,7 @@ ItaniumABILanguageRuntime::ClearExceptio
if (!m_process)
return;
- if (m_cxx_exception_bp_sp.get())
+ if (m_cxx_exception_bp_sp)
{
m_cxx_exception_bp_sp->SetEnabled (false);
}
Modified: lldb/branches/windows/source/Plugins/LanguageRuntime/CPlusPlus/ItaniumABI/ItaniumABILanguageRuntime.h
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/windows/source/Plugins/LanguageRuntime/CPlusPlus/ItaniumABI/ItaniumABILanguageRuntime.h?rev=179679&r1=179678&r2=179679&view=diff
==============================================================================
--- lldb/branches/windows/source/Plugins/LanguageRuntime/CPlusPlus/ItaniumABI/ItaniumABILanguageRuntime.h (original)
+++ lldb/branches/windows/source/Plugins/LanguageRuntime/CPlusPlus/ItaniumABI/ItaniumABILanguageRuntime.h Wed Apr 17 03:38:48 2013
@@ -72,14 +72,24 @@ namespace lldb_private {
virtual bool
ExceptionBreakpointsExplainStop (lldb::StopInfoSP stop_reason);
-
- protected:
+
virtual lldb::BreakpointResolverSP
CreateExceptionResolver (Breakpoint *bkpt, bool catch_bp, bool throw_bp);
+
+ virtual lldb::SearchFilterSP
+ CreateExceptionSearchFilter ();
- virtual lldb::BreakpointResolverSP
+ protected:
+
+ lldb::BreakpointResolverSP
CreateExceptionResolver (Breakpoint *bkpt, bool catch_bp, bool throw_bp, bool for_expressions);
+ lldb::BreakpointSP
+ CreateExceptionBreakpoint(bool catch_bp,
+ bool throw_bp,
+ bool for_expressions,
+ bool is_internal);
+
private:
ItaniumABILanguageRuntime(Process *process) : lldb_private::CPPLanguageRuntime(process) { } // Call CreateInstance instead.
Modified: lldb/branches/windows/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntime.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/windows/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntime.cpp?rev=179679&r1=179678&r2=179679&view=diff
==============================================================================
--- lldb/branches/windows/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntime.cpp (original)
+++ lldb/branches/windows/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntime.cpp Wed Apr 17 03:38:48 2013
@@ -134,9 +134,10 @@ AppleObjCRuntime::GetObjectDescription (
lldb::addr_t wrapper_struct_addr = LLDB_INVALID_ADDRESS;
func.InsertFunction(exe_ctx, wrapper_struct_addr, error_stream);
- bool unwind_on_error = true;
- bool try_all_threads = true;
- bool stop_others = true;
+ const bool unwind_on_error = true;
+ const bool try_all_threads = true;
+ const bool stop_others = true;
+ const bool ignore_breakpoints = true;
ExecutionResults results = func.ExecuteFunction (exe_ctx,
&wrapper_struct_addr,
@@ -144,7 +145,8 @@ AppleObjCRuntime::GetObjectDescription (
stop_others,
0 /* no timeout */,
try_all_threads,
- unwind_on_error,
+ unwind_on_error,
+ ignore_breakpoints,
ret);
if (results != eExecutionCompleted)
{
@@ -331,11 +333,15 @@ AppleObjCRuntime::SetExceptionBreakpoint
const bool is_internal = true;
if (!m_objc_exception_bp_sp)
+ {
m_objc_exception_bp_sp = LanguageRuntime::CreateExceptionBreakpoint (m_process->GetTarget(),
GetLanguageType(),
catch_bp,
throw_bp,
is_internal);
+ if (m_objc_exception_bp_sp)
+ m_objc_exception_bp_sp->SetBreakpointKind("ObjC exception");
+ }
else
m_objc_exception_bp_sp->SetEnabled(true);
}
@@ -387,3 +393,21 @@ AppleObjCRuntime::CalculateHasNewLiteral
else
return false;
}
+
+lldb::SearchFilterSP
+AppleObjCRuntime::CreateExceptionSearchFilter ()
+{
+ Target &target = m_process->GetTarget();
+
+ if (target.GetArchitecture().GetTriple().getVendor() == llvm::Triple::Apple)
+ {
+ FileSpecList filter_modules;
+ filter_modules.Append(FileSpec("libobjc.A.dylib", false));
+ return target.GetSearchFilterForModuleList(&filter_modules);
+ }
+ else
+ {
+ return LanguageRuntime::CreateExceptionSearchFilter();
+ }
+}
+
Modified: lldb/branches/windows/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntime.h
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/windows/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntime.h?rev=179679&r1=179678&r2=179679&view=diff
==============================================================================
--- lldb/branches/windows/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntime.h (original)
+++ lldb/branches/windows/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntime.h Wed Apr 17 03:38:48 2013
@@ -96,6 +96,10 @@ public:
virtual bool
ExceptionBreakpointsExplainStop (lldb::StopInfoSP stop_reason);
+
+ virtual lldb::SearchFilterSP
+ CreateExceptionSearchFilter ();
+
protected:
Address *
GetPrintForDebuggerAddr();
Modified: lldb/branches/windows/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV1.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/windows/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV1.cpp?rev=179679&r1=179678&r2=179679&view=diff
==============================================================================
--- lldb/branches/windows/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV1.cpp (original)
+++ lldb/branches/windows/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV1.cpp Wed Apr 17 03:38:48 2013
@@ -49,13 +49,26 @@ AppleObjCRuntimeV1::AppleObjCRuntimeV1(P
{
}
+// for V1 runtime we just try to return a class name as that is the minimum level of support
+// required for the data formatters to work
bool
AppleObjCRuntimeV1::GetDynamicTypeAndAddress (ValueObject &in_value,
lldb::DynamicValueType use_dynamic,
TypeAndOrName &class_type_or_name,
Address &address)
{
- return false;
+ class_type_or_name.Clear();
+ if (CouldHaveDynamicValue(in_value))
+ {
+ auto class_descriptor(GetClassDescriptor(in_value));
+ if (class_descriptor && class_descriptor->IsValid() && class_descriptor->GetClassName())
+ {
+ const addr_t object_ptr = in_value.GetPointerValue();
+ address.SetRawAddress(object_ptr);
+ class_type_or_name.SetName(class_descriptor->GetClassName());
+ }
+ }
+ return class_type_or_name.IsEmpty() == false;
}
//------------------------------------------------------------------
@@ -351,10 +364,9 @@ AppleObjCRuntimeV1::UpdateISAToDescripto
{
// Update the process stop ID that indicates the last time we updated the
// map, wether it was successful or not.
- m_isa_to_descriptor_cache_stop_id = process->GetStopID();
+ m_isa_to_descriptor_stop_id = process->GetStopID();
-
- lldb::LogSP log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS));
+ Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS));
ProcessSP process_sp = process->shared_from_this();
@@ -385,7 +397,7 @@ AppleObjCRuntimeV1::UpdateISAToDescripto
const uint32_t addr_size = m_process->GetAddressByteSize();
const ByteOrder byte_order = m_process->GetByteOrder();
DataExtractor data (buffer.GetBytes(), buffer.GetByteSize(), byte_order, addr_size);
- uint32_t offset = addr_size; // Skip prototype
+ lldb::offset_t offset = addr_size; // Skip prototype
const uint32_t count = data.GetU32(&offset);
const uint32_t num_buckets = data.GetU32(&offset);
const addr_t buckets_ptr = data.GetPointer(&offset);
@@ -418,14 +430,14 @@ AppleObjCRuntimeV1::UpdateISAToDescripto
isa = bucket_data;
if (isa)
{
- if (m_isa_to_descriptor_cache.count(isa) == 0)
+ if (!ISAIsCached(isa))
{
ClassDescriptorSP descriptor_sp (new ClassDescriptorV1(isa, process_sp));
if (log && log->GetVerbose())
log->Printf("AppleObjCRuntimeV1 added (ObjCISA)0x%" PRIx64 " from _objc_debug_class_hash to isa->descriptor cache", isa);
- m_isa_to_descriptor_cache[isa] = descriptor_sp;
+ AddClass (isa, descriptor_sp);
}
}
}
@@ -440,14 +452,14 @@ AppleObjCRuntimeV1::UpdateISAToDescripto
if (isa && isa != LLDB_INVALID_ADDRESS)
{
- if (m_isa_to_descriptor_cache.count(isa) == 0)
+ if (!ISAIsCached(isa))
{
ClassDescriptorSP descriptor_sp (new ClassDescriptorV1(isa, process_sp));
if (log && log->GetVerbose())
log->Printf("AppleObjCRuntimeV1 added (ObjCISA)0x%" PRIx64 " from _objc_debug_class_hash to isa->descriptor cache", isa);
- m_isa_to_descriptor_cache[isa] = descriptor_sp;
+ AddClass (isa, descriptor_sp);
}
}
}
@@ -460,7 +472,7 @@ AppleObjCRuntimeV1::UpdateISAToDescripto
}
else
{
- m_isa_to_descriptor_cache_stop_id = UINT32_MAX;
+ m_isa_to_descriptor_stop_id = UINT32_MAX;
}
}
Modified: lldb/branches/windows/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV1.h
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/windows/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV1.h?rev=179679&r1=179678&r2=179679&view=diff
==============================================================================
--- lldb/branches/windows/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV1.h (original)
+++ lldb/branches/windows/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV1.h Wed Apr 17 03:38:48 2013
@@ -46,10 +46,12 @@ public:
return m_valid;
}
+ // v1 does not support tagged pointers
virtual bool
- IsTagged ()
+ GetTaggedPointerInfo (uint64_t* info_bits = NULL,
+ uint64_t* value_bits = NULL)
{
- return false; // v1 runtime does not support tagged pointers
+ return false;
}
virtual uint64_t
Modified: lldb/branches/windows/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV2.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/windows/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV2.cpp?rev=179679&r1=179678&r2=179679&view=diff
==============================================================================
--- lldb/branches/windows/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV2.cpp (original)
+++ lldb/branches/windows/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV2.cpp Wed Apr 17 03:38:48 2013
@@ -18,10 +18,8 @@
#include "lldb/Core/ClangForward.h"
#include "lldb/Symbol/ClangASTType.h"
-#include "lldb/Breakpoint/BreakpointLocation.h"
#include "lldb/Core/ClangForward.h"
#include "lldb/Core/ConstString.h"
-#include "lldb/Core/DataBufferMemoryMap.h"
#include "lldb/Core/Error.h"
#include "lldb/Core/Log.h"
#include "lldb/Core/Module.h"
@@ -29,7 +27,7 @@
#include "lldb/Core/Scalar.h"
#include "lldb/Core/Section.h"
#include "lldb/Core/StreamString.h"
-#include "lldb/Core/ValueObjectConstResult.h"
+#include "lldb/Core/Timer.h"
#include "lldb/Expression/ClangFunction.h"
#include "lldb/Expression/ClangUtilityFunction.h"
#include "lldb/Symbol/ClangASTContext.h"
@@ -50,67 +48,255 @@
using namespace lldb;
using namespace lldb_private;
-
static const char *pluginName = "AppleObjCRuntimeV2";
static const char *pluginDesc = "Apple Objective C Language Runtime - Version 2";
static const char *pluginShort = "language.apple.objc.v2";
+// 2 second timeout when running utility functions
+#define UTILITY_FUNCTION_TIMEOUT_USEC 2*1000*1000
+
+static const char *g_get_dynamic_class_info_name = "__lldb_apple_objc_v2_get_dynamic_class_info";
+// Testing using the new C++11 raw string literals. If this breaks GCC then we will
+// need to revert to the code above...
+static const char *g_get_dynamic_class_info_body =
+"\n"
+"extern \"C\"\n"
+"{\n"
+" size_t strlen(const char *);\n"
+" char *strncpy (char * s1, const char * s2, size_t n);\n"
+" int printf(const char * format, ...);\n"
+"}\n"
+"//#define ENABLE_DEBUG_PRINTF // COMMENT THIS LINE OUT PRIOR TO CHECKIN\n"
+"#ifdef ENABLE_DEBUG_PRINTF\n"
+"#define DEBUG_PRINTF(fmt, ...) printf(fmt, ## __VA_ARGS__)\n"
+"#else\n"
+"#define DEBUG_PRINTF(fmt, ...)\n"
+"#endif\n"
+"\n"
+"typedef struct _NXMapTable {\n"
+" void *prototype;\n"
+" unsigned num_classes;\n"
+" unsigned num_buckets_minus_one;\n"
+" void *buckets;\n"
+"} NXMapTable;\n"
+"\n"
+"#define NX_MAPNOTAKEY ((void *)(-1))\n"
+"\n"
+"typedef struct BucketInfo\n"
+"{\n"
+" const char *name_ptr;\n"
+" Class isa;\n"
+"} BucketInfo;\n"
+"\n"
+"struct ClassInfo\n"
+"{\n"
+" Class isa;\n"
+" uint32_t hash;\n"
+"} __attribute__((__packed__));\n"
+"\n"
+"uint32_t\n"
+"__lldb_apple_objc_v2_get_dynamic_class_info (void *gdb_objc_realized_classes_ptr,\n"
+" void *class_infos_ptr,\n"
+" uint32_t class_infos_byte_size)\n"
+"{\n"
+" DEBUG_PRINTF (\"gdb_objc_realized_classes_ptr = %p\\n\", gdb_objc_realized_classes_ptr);\n"
+" DEBUG_PRINTF (\"class_infos_ptr = %p\\n\", class_infos_ptr);\n"
+" DEBUG_PRINTF (\"class_infos_byte_size = %u\\n\", class_infos_byte_size);\n"
+" const NXMapTable *grc = (const NXMapTable *)gdb_objc_realized_classes_ptr;\n"
+" if (grc)\n"
+" {\n"
+" const unsigned num_classes = grc->num_classes;\n"
+" if (class_infos_ptr)\n"
+" {\n"
+" const size_t max_class_infos = class_infos_byte_size/sizeof(ClassInfo);\n"
+" ClassInfo *class_infos = (ClassInfo *)class_infos_ptr;\n"
+" BucketInfo *buckets = (BucketInfo *)grc->buckets;\n"
+" \n"
+" uint32_t idx = 0;\n"
+" for (unsigned i=0; i<=grc->num_buckets_minus_one; ++i)\n"
+" {\n"
+" if (buckets[i].name_ptr != NX_MAPNOTAKEY)\n"
+" {\n"
+" if (idx < max_class_infos)\n"
+" {\n"
+" const char *s = buckets[i].name_ptr;\n"
+" uint32_t h = 5381;\n"
+" for (unsigned char c = *s; c; c = *++s)\n"
+" h = ((h << 5) + h) + c;\n"
+" class_infos[idx].hash = h;\n"
+" class_infos[idx].isa = buckets[i].isa;\n"
+" }\n"
+" ++idx;\n"
+" }\n"
+" }\n"
+" if (idx < max_class_infos)\n"
+" {\n"
+" class_infos[idx].isa = NULL;\n"
+" class_infos[idx].hash = 0;\n"
+" }\n"
+" }\n"
+" return num_classes;\n"
+" }\n"
+" return 0;\n"
+"}\n"
+"\n";
+
+static const char *g_get_shared_cache_class_info_name = "__lldb_apple_objc_v2_get_shared_cache_class_info";
+// Testing using the new C++11 raw string literals. If this breaks GCC then we will
+// need to revert to the code above...
+static const char *g_get_shared_cache_class_info_body =
+ "\n"
+"extern \"C\"\n"
+"{\n"
+" const char *class_getName(void *objc_class);\n"
+" size_t strlen(const char *);\n"
+" char *strncpy (char * s1, const char * s2, size_t n);\n"
+" int printf(const char * format, ...);\n"
+"}\n"
+"\n"
+"//#define ENABLE_DEBUG_PRINTF // COMMENT THIS LINE OUT PRIOR TO CHECKIN\n"
+"#ifdef ENABLE_DEBUG_PRINTF\n"
+"#define DEBUG_PRINTF(fmt, ...) printf(fmt, ## __VA_ARGS__)\n"
+"#else\n"
+"#define DEBUG_PRINTF(fmt, ...)\n"
+"#endif\n"
+"\n"
+"\n"
+"struct objc_classheader_t {\n"
+" int32_t clsOffset;\n"
+" int32_t hiOffset;\n"
+"};\n"
+"\n"
+"struct objc_clsopt_t {\n"
+" uint32_t capacity;\n"
+" uint32_t occupied;\n"
+" uint32_t shift;\n"
+" uint32_t mask;\n"
+" uint32_t zero;\n"
+" uint32_t unused;\n"
+" uint64_t salt;\n"
+" uint32_t scramble[256];\n"
+" uint8_t tab[0]; // tab[mask+1]\n"
+" // uint8_t checkbytes[capacity];\n"
+" // int32_t offset[capacity];\n"
+" // objc_classheader_t clsOffsets[capacity];\n"
+" // uint32_t duplicateCount;\n"
+" // objc_classheader_t duplicateOffsets[duplicateCount];\n"
+"};\n"
+"\n"
+"struct objc_opt_t {\n"
+" uint32_t version;\n"
+" int32_t selopt_offset;\n"
+" int32_t headeropt_offset;\n"
+" int32_t clsopt_offset;\n"
+"};\n"
+"\n"
+"struct ClassInfo\n"
+"{\n"
+" Class isa;\n"
+" uint32_t hash;\n"
+"} __attribute__((__packed__));\n"
+"\n"
+"uint32_t\n"
+"__lldb_apple_objc_v2_get_shared_cache_class_info (void *objc_opt_ro_ptr,\n"
+" void *class_infos_ptr,\n"
+" uint32_t class_infos_byte_size)\n"
+"{\n"
+" uint32_t idx = 0;\n"
+" DEBUG_PRINTF (\"objc_opt_ro_ptr = %p\\n\", objc_opt_ro_ptr);\n"
+" DEBUG_PRINTF (\"class_infos_ptr = %p\\n\", class_infos_ptr);\n"
+" DEBUG_PRINTF (\"class_infos_byte_size = %u (%zu class infos)\\n\", class_infos_byte_size, (size_t)(class_infos_byte_size/sizeof(ClassInfo)));\n"
+" if (objc_opt_ro_ptr)\n"
+" {\n"
+" const objc_opt_t *objc_opt = (objc_opt_t *)objc_opt_ro_ptr;\n"
+" DEBUG_PRINTF (\"objc_opt->version = %u\\n\", objc_opt->version);\n"
+" DEBUG_PRINTF (\"objc_opt->selopt_offset = %d\\n\", objc_opt->selopt_offset);\n"
+" DEBUG_PRINTF (\"objc_opt->headeropt_offset = %d\\n\", objc_opt->headeropt_offset);\n"
+" DEBUG_PRINTF (\"objc_opt->clsopt_offset = %d\\n\", objc_opt->clsopt_offset);\n"
+" if (objc_opt->version == 12)\n"
+" {\n"
+" const objc_clsopt_t* clsopt = (const objc_clsopt_t*)((uint8_t *)objc_opt + objc_opt->clsopt_offset);\n"
+" const size_t max_class_infos = class_infos_byte_size/sizeof(ClassInfo);\n"
+" ClassInfo *class_infos = (ClassInfo *)class_infos_ptr;\n"
+" int32_t zeroOffset = 16;\n"
+" const uint8_t *checkbytes = &clsopt->tab[clsopt->mask+1];\n"
+" const int32_t *offsets = (const int32_t *)(checkbytes + clsopt->capacity);\n"
+" const objc_classheader_t *classOffsets = (const objc_classheader_t *)(offsets + clsopt->capacity);\n"
+" DEBUG_PRINTF (\"clsopt->capacity = %u\\n\", clsopt->capacity);\n"
+" DEBUG_PRINTF (\"clsopt->mask = 0x%8.8x\\n\", clsopt->mask);\n"
+" DEBUG_PRINTF (\"classOffsets = %p\\n\", classOffsets);\n"
+" for (uint32_t i=0; i<clsopt->capacity; ++i)\n"
+" {\n"
+" const int32_t clsOffset = classOffsets[i].clsOffset;\n"
+" if (clsOffset & 1)\n"
+" continue; // duplicate\n"
+" else if (clsOffset == zeroOffset)\n"
+" continue; // zero offset\n"
+" \n"
+" if (class_infos && idx < max_class_infos)\n"
+" {\n"
+" class_infos[idx].isa = (Class)((uint8_t *)clsopt + clsOffset);\n"
+" const char *name = class_getName (class_infos[idx].isa);\n"
+" DEBUG_PRINTF (\"[%u] isa = %8p %s\\n\", idx, class_infos[idx].isa, name);\n"
+" // Hash the class name so we don't have to read it\n"
+" const char *s = name;\n"
+" uint32_t h = 5381;\n"
+" for (unsigned char c = *s; c; c = *++s)\n"
+" h = ((h << 5) + h) + c;\n"
+" class_infos[idx].hash = h;\n"
+" }\n"
+" ++idx;\n"
+" }\n"
+" \n"
+" const uint32_t *duplicate_count_ptr = (uint32_t *)&classOffsets[clsopt->capacity];\n"
+" const uint32_t duplicate_count = *duplicate_count_ptr;\n"
+" const objc_classheader_t *duplicateClassOffsets = (const objc_classheader_t *)(&duplicate_count_ptr[1]);\n"
+" DEBUG_PRINTF (\"duplicate_count = %u\\n\", duplicate_count);\n"
+" DEBUG_PRINTF (\"duplicateClassOffsets = %p\\n\", duplicateClassOffsets);\n"
+" for (uint32_t i=0; i<duplicate_count; ++i)\n"
+" {\n"
+" const int32_t clsOffset = duplicateClassOffsets[i].clsOffset;\n"
+" if (clsOffset & 1)\n"
+" continue; // duplicate\n"
+" else if (clsOffset == zeroOffset)\n"
+" continue; // zero offset\n"
+" \n"
+" if (class_infos && idx < max_class_infos)\n"
+" {\n"
+" class_infos[idx].isa = (Class)((uint8_t *)clsopt + clsOffset);\n"
+" const char *name = class_getName (class_infos[idx].isa);\n"
+" DEBUG_PRINTF (\"[%u] isa = %8p %s\\n\", idx, class_infos[idx].isa, name);\n"
+" // Hash the class name so we don't have to read it\n"
+" const char *s = name;\n"
+" uint32_t h = 5381;\n"
+" for (unsigned char c = *s; c; c = *++s)\n"
+" h = ((h << 5) + h) + c;\n"
+" class_infos[idx].hash = h;\n"
+" }\n"
+" ++idx;\n"
+" }\n"
+" }\n"
+" DEBUG_PRINTF (\"%u class_infos\\n\", idx);\n"
+" DEBUG_PRINTF (\"done\\n\");\n"
+" }\n"
+" return idx;\n"
+"}\n"
+"\n"
+"\n";
-const char *AppleObjCRuntimeV2::g_find_class_name_function_name = "__lldb_apple_objc_v2_find_class_name";
-const char *AppleObjCRuntimeV2::g_find_class_name_function_body = " \n\
-extern \"C\" \n\
-{ \n\
- extern void *gdb_class_getClass (void *objc_class); \n\
- extern void *class_getName(void *objc_class); \n\
- extern int printf(const char *format, ...); \n\
- extern unsigned char class_isMetaClass (void *objc_class); \n\
-} \n\
- \n\
-struct __lldb_objc_object { \n\
- void *isa; \n\
-}; \n\
- \n\
-extern \"C\" void *__lldb_apple_objc_v2_find_class_name ( \n\
- __lldb_objc_object *object_ptr, \n\
- int debug) \n\
-{ \n\
- void *name = 0; \n\
- if (debug) \n\
- printf (\"\\n*** Called in v2_find_class_name with object: 0x%p\\n\", object_ptr); \n\
- // Call gdb_class_getClass so we can tell if the class is good. \n\
- void *objc_class = gdb_class_getClass (object_ptr->isa); \n\
- if (objc_class) \n\
- { \n\
- void *actual_class = (void *) [(id) object_ptr class]; \n\
- if (actual_class != 0) \n\
- { \n\
- if (class_isMetaClass(actual_class) == 1) \n\
- { \n\
- if (debug) \n\
- printf (\"\\n*** Found metaclass.\\n\"); \n\
- } \n\
- else \n\
- { \n\
- name = class_getName((void *) actual_class); \n\
- } \n\
- } \n\
- if (debug) \n\
- printf (\"\\n*** Found name: %s\\n\", name ? name : \"<NOT FOUND>\"); \n\
- } \n\
- else if (debug) \n\
- printf (\"\\n*** gdb_class_getClass returned NULL\\n\"); \n\
- return name; \n\
-} \n\
-";
-AppleObjCRuntimeV2::AppleObjCRuntimeV2 (Process *process,
- const ModuleSP &objc_module_sp) :
+AppleObjCRuntimeV2::AppleObjCRuntimeV2 (Process *process,
+ const ModuleSP &objc_module_sp) :
AppleObjCRuntime (process),
- m_get_class_name_function (),
- m_get_class_name_code (),
- m_get_class_name_args (LLDB_INVALID_ADDRESS),
- m_get_class_name_args_mutex (Mutex::eMutexTypeNormal),
+ m_get_class_info_function(),
+ m_get_class_info_code(),
+ m_get_class_info_args (LLDB_INVALID_ADDRESS),
+ m_get_class_info_args_mutex (Mutex::eMutexTypeNormal),
+ m_get_shared_cache_class_info_function(),
+ m_get_shared_cache_class_info_code(),
+ m_get_shared_cache_class_info_args (LLDB_INVALID_ADDRESS),
+ m_get_shared_cache_class_info_args_mutex (Mutex::eMutexTypeNormal),
m_type_vendor_ap (),
m_isa_hash_table_ptr (LLDB_INVALID_ADDRESS),
m_hash_signature (),
@@ -122,137 +308,6 @@ AppleObjCRuntimeV2::AppleObjCRuntimeV2 (
}
bool
-AppleObjCRuntimeV2::RunFunctionToFindClassName(addr_t object_addr, Thread *thread, char *name_dst, size_t max_name_len)
-{
- // Since we are going to run code we have to make sure only one thread at a time gets to try this.
- Mutex::Locker locker(m_get_class_name_args_mutex);
-
- StreamString errors;
-
- LogSP log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP)); // FIXME - a more appropriate log channel?
-
- int32_t debug;
- if (log && log->GetVerbose())
- debug = 1;
- else
- debug = 0;
-
- ValueList dispatch_values;
-
- Value void_ptr_value;
- ClangASTContext *clang_ast_context = m_process->GetTarget().GetScratchClangASTContext();
-
- clang_type_t clang_void_ptr_type = clang_ast_context->GetVoidPtrType(false);
- void_ptr_value.SetValueType (Value::eValueTypeScalar);
- void_ptr_value.SetContext (Value::eContextTypeClangType, clang_void_ptr_type);
- void_ptr_value.GetScalar() = object_addr;
-
- dispatch_values.PushValue (void_ptr_value);
-
- Value int_value;
- clang_type_t clang_int_type = clang_ast_context->GetBuiltinTypeForEncodingAndBitSize(eEncodingSint, 32);
- int_value.SetValueType (Value::eValueTypeScalar);
- int_value.SetContext (Value::eContextTypeClangType, clang_int_type);
- int_value.GetScalar() = debug;
-
- dispatch_values.PushValue (int_value);
-
- ExecutionContext exe_ctx;
- thread->CalculateExecutionContext(exe_ctx);
-
- Address find_class_name_address;
-
- if (!m_get_class_name_code.get())
- {
- m_get_class_name_code.reset (new ClangUtilityFunction (g_find_class_name_function_body,
- g_find_class_name_function_name));
-
- if (!m_get_class_name_code->Install(errors, exe_ctx))
- {
- if (log)
- log->Printf ("Failed to install implementation lookup: %s.", errors.GetData());
- m_get_class_name_code.reset();
- return false;
- }
- find_class_name_address.Clear();
- find_class_name_address.SetOffset(m_get_class_name_code->StartAddress());
- }
- else
- {
- find_class_name_address.Clear();
- find_class_name_address.SetOffset(m_get_class_name_code->StartAddress());
- }
-
- // Next make the runner function for our implementation utility function.
- if (!m_get_class_name_function.get())
- {
- m_get_class_name_function.reset(new ClangFunction (*m_process,
- clang_ast_context,
- clang_void_ptr_type,
- find_class_name_address,
- dispatch_values));
-
- errors.Clear();
- unsigned num_errors = m_get_class_name_function->CompileFunction(errors);
- if (num_errors)
- {
- if (log)
- log->Printf ("Error compiling function: \"%s\".", errors.GetData());
- return false;
- }
-
- errors.Clear();
- if (!m_get_class_name_function->WriteFunctionWrapper(exe_ctx, errors))
- {
- if (log)
- log->Printf ("Error Inserting function: \"%s\".", errors.GetData());
- return false;
- }
- }
-
- if (m_get_class_name_code.get() == NULL || m_get_class_name_function.get() == NULL)
- return false;
-
- // Finally, write down the arguments, and call the function. Note that we will re-use the same space in the target
- // for the args. We're locking this to ensure that only one thread at a time gets to call this function, so we don't
- // have to worry about overwriting the arguments.
-
- if (!m_get_class_name_function->WriteFunctionArguments (exe_ctx, m_get_class_name_args, find_class_name_address, dispatch_values, errors))
- return false;
-
- bool stop_others = true;
- bool try_all_threads = true;
- bool unwind_on_error = true;
-
- ExecutionResults results = m_get_class_name_function->ExecuteFunction (exe_ctx,
- &m_get_class_name_args,
- errors,
- stop_others,
- 100000,
- try_all_threads,
- unwind_on_error,
- void_ptr_value);
-
- if (results != eExecutionCompleted)
- {
- if (log)
- log->Printf("Error evaluating our find class name function: %d.\n", results);
- return false;
- }
-
- addr_t result_ptr = void_ptr_value.GetScalar().ULongLong(LLDB_INVALID_ADDRESS);
- Error error;
- size_t chars_read = m_process->ReadCStringFromMemory (result_ptr, name_dst, max_name_len, error);
-
- // If we exhausted our buffer before finding a NULL we're probably off in the weeds somewhere...
- if (error.Fail() || chars_read == max_name_len)
- return false;
- else
- return true;
-
-}
-
-bool
AppleObjCRuntimeV2::GetDynamicTypeAndAddress (ValueObject &in_value,
DynamicValueType use_dynamic,
TypeAndOrName &class_type_or_name,
@@ -261,6 +316,8 @@ AppleObjCRuntimeV2::GetDynamicTypeAndAdd
// The Runtime is attached to a particular process, you shouldn't pass in a value from another process.
assert (in_value.GetProcessSP().get() == m_process);
assert (m_process != NULL);
+
+ class_type_or_name.Clear();
// Make sure we can have a dynamic value before starting...
if (CouldHaveDynamicValue (in_value))
@@ -286,12 +343,9 @@ AppleObjCRuntimeV2::GetDynamicTypeAndAdd
class_type_or_name.SetTypeSP (type_sp);
}
}
-
- if (type_sp)
- return true;
}
}
- return false;
+ return class_type_or_name.IsEmpty() == false;
}
//------------------------------------------------------------------
@@ -490,6 +544,15 @@ public:
{
}
+ void
+ Dump ()
+ {
+ printf ("RemoteNXMapTable.m_load_addr = 0x%" PRIx64 "\n", m_load_addr);
+ printf ("RemoteNXMapTable.m_count = %u\n", m_count);
+ printf ("RemoteNXMapTable.m_num_buckets_minus_one = %u\n", m_num_buckets_minus_one);
+ printf ("RemoteNXMapTable.m_buckets_ptr = 0x%" PRIX64 "\n", m_buckets_ptr);
+ }
+
bool
ParseHeader (Process* process, lldb::addr_t load_addr)
{
@@ -670,6 +733,12 @@ public:
{
return m_buckets_ptr;
}
+
+ lldb::addr_t
+ GetTableLoadAddress() const
+ {
+ return m_load_addr;
+ }
private:
// contents of _NXMapTable struct
@@ -721,236 +790,6 @@ AppleObjCRuntimeV2::HashTableSignature::
return true;
}
-class RemoteObjCOpt
-{
-public:
- RemoteObjCOpt (Process* process,
- lldb::addr_t load_addr) :
- m_process(process),
- m_end_iterator(*this, -1ll),
- m_load_addr(load_addr),
- m_classheader_size(sizeof(int32_t) * 2)
- {
- lldb::addr_t cursor = load_addr;
-
- Error err;
-
- // uint32_t version;
- m_version = m_process->ReadUnsignedIntegerFromMemory(cursor, sizeof(uint32_t), 0, err);
- cursor += sizeof(uint32_t);
-
- if (!IsValid())
- return;
-
- // int32_t selopt_offset;
- cursor += sizeof(int32_t);
-
- // int32_t headeropt_offset;
- cursor += sizeof(int32_t);
-
- // int32_t clsopt_offset;
- {
- Scalar clsopt_offset;
- m_process->ReadScalarIntegerFromMemory(cursor, sizeof(int32_t), /*is_signed*/ true, clsopt_offset, err);
- m_clsopt_offset = clsopt_offset.SInt();
- cursor += sizeof(int32_t);
- }
-
- m_clsopt_ptr = load_addr + m_clsopt_offset;
-
- cursor = m_clsopt_ptr;
-
- // uint32_t capacity;
- m_capacity = m_process->ReadUnsignedIntegerFromMemory(cursor, sizeof(uint32_t), 0, err);
- cursor += sizeof(uint32_t);
-
- // uint32_t occupied;
- cursor += sizeof(uint32_t);
-
- // uint32_t shift;
- cursor += sizeof(uint32_t);
-
- // uint32_t mask;
- m_mask = m_process->ReadUnsignedIntegerFromMemory(cursor, sizeof(uint32_t), 0, err);
- cursor += sizeof(uint32_t);
-
- // uint32_t zero;
- m_zero_offset = cursor - m_clsopt_ptr;
- cursor += sizeof(uint32_t);
-
- // uint32_t unused;
- cursor += sizeof(uint32_t);
-
- // uint64_t salt;
- cursor += sizeof(uint64_t);
-
- // uint32_t scramble[256];
- cursor += sizeof(uint32_t) * 256;
-
- // uint8_t tab[mask+1];
- cursor += sizeof(uint8_t) * (m_mask + 1);
-
- // uint8_t checkbytes[capacity];
- cursor += sizeof(uint8_t) * m_capacity;
-
- // int32_t offset[capacity];
- cursor += sizeof(int32_t) * m_capacity;
-
- // objc_classheader_t clsOffsets[capacity];
- m_clsOffsets_ptr = cursor;
- cursor += (m_classheader_size * m_capacity);
-
- // uint32_t duplicateCount;
- m_duplicateCount = m_process->ReadUnsignedIntegerFromMemory(cursor, sizeof(uint32_t), 0, err);
- cursor += sizeof(uint32_t);
-
- // objc_classheader_t duplicateOffsets[duplicateCount];
- m_duplicateOffsets_ptr = cursor;
- }
-
- friend class const_iterator;
- class const_iterator
- {
- public:
- const_iterator (RemoteObjCOpt &parent, int64_t index) : m_parent(parent), m_index(index)
- {
- AdvanceToValidIndex();
- }
-
- const_iterator (const const_iterator &rhs) : m_parent(rhs.m_parent), m_index(rhs.m_index)
- {
- // AdvanceToValidIndex() has been called by rhs already
- }
-
- const_iterator &operator=(const const_iterator &rhs)
- {
- assert (&m_parent == &rhs.m_parent);
- m_index = rhs.m_index;
- return *this;
- }
-
- bool operator==(const const_iterator &rhs) const
- {
- if (&m_parent != &rhs.m_parent)
- return false;
- if (m_index != rhs.m_index)
- return false;
- return true;
- }
-
- bool operator!=(const const_iterator &rhs) const
- {
- return !(operator==(rhs));
- }
-
- const_iterator &operator++()
- {
- AdvanceToValidIndex();
- return *this;
- }
-
- ObjCLanguageRuntime::ObjCISA operator*() const
- {
- if (m_index == -1)
- return 0;
-
- Error err;
- return isaForIndex(err);
- }
- private:
- ObjCLanguageRuntime::ObjCISA isaForIndex(Error &err) const
- {
- if (m_index >= m_parent.m_capacity + m_parent.m_duplicateCount)
- return 0; // index out of range
-
- lldb::addr_t classheader_ptr;
-
- if (m_index >= m_parent.m_capacity)
- {
- // index in the duplicate offsets
- uint32_t index = (uint32_t)((uint64_t)m_index - (uint64_t)m_parent.m_capacity);
- classheader_ptr = m_parent.m_duplicateOffsets_ptr + (index * m_parent.m_classheader_size);
- }
- else
- {
- // index in the offsets
- uint32_t index = (uint32_t)m_index;
- classheader_ptr = m_parent.m_clsOffsets_ptr + (index * m_parent.m_classheader_size);
- }
-
- Scalar clsOffset;
- m_parent.m_process->ReadScalarIntegerFromMemory(classheader_ptr, sizeof(int32_t), /*is_signed*/ true, clsOffset, err);
- if (!err.Success())
- return 0;
-
- int32_t clsOffset_int = clsOffset.SInt();
- if (clsOffset_int & 0x1)
- return 0; // not even
-
- if (clsOffset_int == m_parent.m_zero_offset)
- return 0; // == offsetof(objc_clsopt_t, zero)
-
- return m_parent.m_clsopt_ptr + (int64_t)clsOffset_int;
- }
-
- void AdvanceToValidIndex ()
- {
- if (m_index == -1)
- return;
-
- Error err;
-
- m_index--;
-
- while (m_index >= 0)
- {
- ObjCLanguageRuntime::ObjCISA objc_isa = isaForIndex(err);
- if (objc_isa)
- return;
- m_index--;
- }
- }
- RemoteObjCOpt &m_parent;
- int64_t m_index;
- };
-
- const_iterator begin ()
- {
- if (!IsValid())
- return m_end_iterator;
- else
- return const_iterator(*this, (int64_t)m_capacity + (int64_t)m_duplicateCount);
- }
-
- const_iterator end ()
- {
- return m_end_iterator;
- }
-
-private:
- bool IsValid()
- {
- return (m_version == 12);
- }
-
- // contents of objc_opt struct
- uint32_t m_version;
- int32_t m_clsopt_offset;
- lldb::addr_t m_clsopt_ptr;
-
- // contents of objc_clsopt struct
- uint32_t m_capacity;
- uint32_t m_mask;
- uint32_t m_duplicateCount;
- lldb::addr_t m_clsOffsets_ptr;
- lldb::addr_t m_duplicateOffsets_ptr;
- int32_t m_zero_offset;
- lldb_private::Process *m_process;
- const_iterator m_end_iterator;
- lldb::addr_t m_load_addr;
- const size_t m_classheader_size;
-};
-
class ClassDescriptorV2 : public ObjCLanguageRuntime::ClassDescriptor
{
public:
@@ -965,7 +804,7 @@ private:
m_name (name)
{
}
-
+
public:
virtual ConstString
GetClassName ()
@@ -1013,10 +852,12 @@ public:
return true; // any Objective-C v2 runtime class descriptor we vend is valid
}
+ // a custom descriptor is used for tagged pointers
virtual bool
- IsTagged ()
+ GetTaggedPointerInfo (uint64_t* info_bits = NULL,
+ uint64_t* value_bits = NULL)
{
- return false; // we use a special class for tagged descriptors
+ return false;
}
virtual uint64_t
@@ -1189,7 +1030,7 @@ private:
DataExtractor extractor(objc_class_buf.GetBytes(), objc_class_size, process->GetByteOrder(), process->GetAddressByteSize());
- uint32_t cursor = 0;
+ lldb::offset_t cursor = 0;
m_isa = extractor.GetAddress_unchecked(&cursor); // uintptr_t isa;
m_superclass = extractor.GetAddress_unchecked(&cursor); // Class superclass;
@@ -1248,7 +1089,7 @@ private:
DataExtractor extractor(buffer.GetBytes(), size, process->GetByteOrder(), process->GetAddressByteSize());
- uint32_t cursor = 0;
+ lldb::offset_t cursor = 0;
m_flags = extractor.GetU32_unchecked(&cursor);
m_instanceStart = extractor.GetU32_unchecked(&cursor);
@@ -1319,13 +1160,13 @@ private:
DataExtractor extractor(buffer.GetBytes(), size, process->GetByteOrder(), process->GetAddressByteSize());
- uint32_t cursor = 0;
+ lldb::offset_t cursor = 0;
m_flags = extractor.GetU32_unchecked(&cursor);
m_version = extractor.GetU32_unchecked(&cursor);
- m_ro_ptr = extractor.GetAddress_unchecked(&cursor);
- m_method_list_ptr = extractor.GetAddress_unchecked(&cursor);
- m_properties_ptr = extractor.GetAddress_unchecked(&cursor);
+ m_ro_ptr = extractor.GetAddress_unchecked(&cursor);
+ m_method_list_ptr = extractor.GetAddress_unchecked(&cursor);
+ m_properties_ptr = extractor.GetAddress_unchecked(&cursor);
m_firstSubclass = extractor.GetAddress_unchecked(&cursor);
m_nextSiblingClass = extractor.GetAddress_unchecked(&cursor);
@@ -1355,7 +1196,7 @@ private:
DataExtractor extractor(buffer.GetBytes(), size, process->GetByteOrder(), process->GetAddressByteSize());
- uint32_t cursor = 0;
+ lldb::offset_t cursor = 0;
m_entsize = extractor.GetU32_unchecked(&cursor) & ~(uint32_t)3;
m_count = extractor.GetU32_unchecked(&cursor);
@@ -1398,7 +1239,7 @@ private:
DataExtractor extractor(buffer.GetBytes(), size, process->GetByteOrder(), process->GetAddressByteSize());
- uint32_t cursor = 0;
+ lldb::offset_t cursor = 0;
m_name_ptr = extractor.GetAddress_unchecked(&cursor);
m_types_ptr = extractor.GetAddress_unchecked(&cursor);
@@ -1441,7 +1282,7 @@ private:
DataExtractor extractor(buffer.GetBytes(), size, process->GetByteOrder(), process->GetAddressByteSize());
- uint32_t cursor = 0;
+ lldb::offset_t cursor = 0;
m_entsize = extractor.GetU32_unchecked(&cursor);
m_count = extractor.GetU32_unchecked(&cursor);
@@ -1488,7 +1329,7 @@ private:
DataExtractor extractor(buffer.GetBytes(), size, process->GetByteOrder(), process->GetAddressByteSize());
- uint32_t cursor = 0;
+ lldb::offset_t cursor = 0;
m_offset_ptr = extractor.GetAddress_unchecked(&cursor);
m_name_ptr = extractor.GetAddress_unchecked(&cursor);
@@ -1592,16 +1433,16 @@ public:
m_class_bits = (value & 0xE) >> 1;
lldb::TargetSP target_sp = isa_pointer.GetTargetSP();
- LazyBool is_lion = IsLion(target_sp);
+ uint32_t foundation_version = GetFoundationVersion(target_sp);
// TODO: check for OSX version - for now assume Mtn Lion
- if (is_lion == eLazyBoolCalculate)
+ if (foundation_version == UINT32_MAX)
{
// if we can't determine the matching table (e.g. we have no Foundation),
// assume this is not a valid tagged pointer
m_valid = false;
}
- else if (is_lion == eLazyBoolNo)
+ else if (foundation_version >= 900)
{
switch (m_class_bits)
{
@@ -1667,7 +1508,7 @@ public:
// tagged pointers can represent a class that has a superclass, but since that information is not
// stored in the object itself, we would have to query the runtime to discover the hierarchy
// for the time being, we skip this step in the interest of static discovery
- return ObjCLanguageRuntime::ClassDescriptorSP(new ObjCLanguageRuntime::ClassDescriptor_Invalid());
+ return ObjCLanguageRuntime::ClassDescriptorSP();
}
virtual bool
@@ -1689,9 +1530,14 @@ public:
}
virtual bool
- IsTagged ()
+ GetTaggedPointerInfo (uint64_t* info_bits = NULL,
+ uint64_t* value_bits = NULL)
{
- return true; // we use this class to describe tagged pointers
+ if (info_bits)
+ *info_bits = GetInfoBits();
+ if (value_bits)
+ *value_bits = GetValueBits();
+ return true;
}
virtual uint64_t
@@ -1730,13 +1576,14 @@ public:
{}
protected:
- // TODO make this into a smarter OS version detector
- LazyBool
- IsLion (lldb::TargetSP &target_sp)
+ // we use the version of Foundation to make assumptions about the ObjC runtime on a target
+ uint32_t
+ GetFoundationVersion (lldb::TargetSP &target_sp)
{
if (!target_sp)
return eLazyBoolCalculate;
const ModuleList& modules = target_sp->GetImages();
+ uint32_t major = UINT32_MAX;
for (uint32_t idx = 0; idx < modules.GetSize(); idx++)
{
lldb::ModuleSP module_sp = modules.GetModuleAtIndex(idx);
@@ -1744,15 +1591,11 @@ protected:
continue;
if (strcmp(module_sp->GetFileSpec().GetFilename().AsCString(""),"Foundation") == 0)
{
- uint32_t major = UINT32_MAX;
module_sp->GetVersion(&major,1);
- if (major == UINT32_MAX)
- return eLazyBoolCalculate;
-
- return (major > 900 ? eLazyBoolNo : eLazyBoolYes);
+ break;
}
}
- return eLazyBoolCalculate;
+ return major;
}
private:
@@ -1800,7 +1643,7 @@ AppleObjCRuntimeV2::GetClassDescriptor (
objc_class_sp = ObjCLanguageRuntime::GetClassDescriptor (isa);
if (isa && !objc_class_sp)
{
- lldb::LogSP log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS));
+ Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS));
if (log)
log->Printf("0x%" PRIx64 ": AppleObjCRuntimeV2::GetClassDescriptor() ISA was not in class descriptor cache 0x%" PRIx64,
isa_pointer,
@@ -1821,6 +1664,9 @@ AppleObjCRuntimeV2::GetISAHashTablePoint
Process *process = GetProcess();
ModuleSP objc_module_sp(GetObjCModule());
+
+ if (!objc_module_sp)
+ return LLDB_INVALID_ADDRESS;
static ConstString g_gdb_objc_realized_classes("gdb_objc_realized_classes");
@@ -1839,102 +1685,573 @@ AppleObjCRuntimeV2::GetISAHashTablePoint
return m_isa_hash_table_ptr;
}
-void
-AppleObjCRuntimeV2::UpdateISAToDescriptorMapIfNeeded()
+bool
+AppleObjCRuntimeV2::UpdateISAToDescriptorMapDynamic(RemoteNXMapTable &hash_table)
{
- // Else we need to check with our process to see when the map was updated.
Process *process = GetProcess();
-
- if (process)
+
+ if (process == NULL)
+ return false;
+
+ Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS));
+
+ ExecutionContext exe_ctx;
+
+ ThreadSP thread_sp = process->GetThreadList().GetSelectedThread();
+
+ if (!thread_sp)
+ return false;
+
+ thread_sp->CalculateExecutionContext(exe_ctx);
+ ClangASTContext *ast = process->GetTarget().GetScratchClangASTContext();
+
+ if (!ast)
+ return false;
+
+ Address function_address;
+
+ StreamString errors;
+
+ const uint32_t addr_size = process->GetAddressByteSize();
+
+ Error err;
+
+ // Read the total number of classes from the hash table
+ const uint32_t num_classes = hash_table.GetCount();
+ if (num_classes == 0)
{
- // Update the process stop ID that indicates the last time we updated the
- // map, wether it was successful or not.
- m_isa_to_descriptor_cache_stop_id = process->GetStopID();
+ if (log)
+ log->Printf ("No dynamic classes found in gdb_objc_realized_classes.");
+ return false;
+ }
+
+ // Make some types for our arguments
+ clang_type_t clang_uint32_t_type = ast->GetBuiltinTypeForEncodingAndBitSize(eEncodingUint, 32);
+ clang_type_t clang_void_pointer_type = ast->CreatePointerType(ast->GetBuiltInType_void());
+
+ if (!m_get_class_info_code.get())
+ {
+ m_get_class_info_code.reset (new ClangUtilityFunction (g_get_dynamic_class_info_body,
+ g_get_dynamic_class_info_name));
- RemoteNXMapTable hash_table;
+ errors.Clear();
+
+ if (!m_get_class_info_code->Install(errors, exe_ctx))
+ {
+ if (log)
+ log->Printf ("Failed to install implementation lookup: %s.", errors.GetData());
+ m_get_class_info_code.reset();
+ }
+ }
+
+ if (m_get_class_info_code.get())
+ function_address.SetOffset(m_get_class_info_code->StartAddress());
+ else
+ return false;
+
+ ValueList arguments;
+
+ // Next make the runner function for our implementation utility function.
+ if (!m_get_class_info_function.get())
+ {
+ Value value;
+ value.SetValueType (Value::eValueTypeScalar);
+ value.SetContext (Value::eContextTypeClangType, clang_void_pointer_type);
+ arguments.PushValue (value);
+
+ value.SetValueType (Value::eValueTypeScalar);
+ value.SetContext (Value::eContextTypeClangType, clang_void_pointer_type);
+ arguments.PushValue (value);
+
+ value.SetValueType (Value::eValueTypeScalar);
+ value.SetContext (Value::eContextTypeClangType, clang_uint32_t_type);
+ arguments.PushValue (value);
+
+ m_get_class_info_function.reset(new ClangFunction (*m_process,
+ ast,
+ clang_uint32_t_type,
+ function_address,
+ arguments));
+
+ if (m_get_class_info_function.get() == NULL)
+ return false;
+
+ errors.Clear();
+
+ unsigned num_errors = m_get_class_info_function->CompileFunction(errors);
+ if (num_errors)
+ {
+ if (log)
+ log->Printf ("Error compiling function: \"%s\".", errors.GetData());
+ return false;
+ }
+
+ errors.Clear();
+
+ if (!m_get_class_info_function->WriteFunctionWrapper(exe_ctx, errors))
+ {
+ if (log)
+ log->Printf ("Error Inserting function: \"%s\".", errors.GetData());
+ return false;
+ }
+ }
+ else
+ {
+ arguments = m_get_class_info_function->GetArgumentValues ();
+ }
+
+ const uint32_t class_info_byte_size = addr_size + 4;
+ const uint32_t class_infos_byte_size = num_classes * class_info_byte_size;
+ lldb::addr_t class_infos_addr = process->AllocateMemory(class_infos_byte_size,
+ ePermissionsReadable | ePermissionsWritable,
+ err);
+
+ if (class_infos_addr == LLDB_INVALID_ADDRESS)
+ return false;
+
+ Mutex::Locker locker(m_get_class_info_args_mutex);
+
+ // Fill in our function argument values
+ arguments.GetValueAtIndex(0)->GetScalar() = hash_table.GetTableLoadAddress();
+ arguments.GetValueAtIndex(1)->GetScalar() = class_infos_addr;
+ arguments.GetValueAtIndex(2)->GetScalar() = class_infos_byte_size;
+
+ bool success = false;
+
+ errors.Clear();
+
+ // Write our function arguments into the process so we can run our function
+ if (m_get_class_info_function->WriteFunctionArguments (exe_ctx,
+ m_get_class_info_args,
+ function_address,
+ arguments,
+ errors))
+ {
+ bool stop_others = true;
+ bool try_all_threads = false;
+ bool unwind_on_error = true;
+ bool ignore_breakpoints = true;
+
+ Value return_value;
+ return_value.SetValueType (Value::eValueTypeScalar);
+ return_value.SetContext (Value::eContextTypeClangType, clang_uint32_t_type);
+ return_value.GetScalar() = 0;
+
+ errors.Clear();
+
+ // Run the function
+ ExecutionResults results = m_get_class_info_function->ExecuteFunction (exe_ctx,
+ &m_get_class_info_args,
+ errors,
+ stop_others,
+ UTILITY_FUNCTION_TIMEOUT_USEC,
+ try_all_threads,
+ unwind_on_error,
+ ignore_breakpoints,
+ return_value);
- if (m_hash_signature.NeedsUpdate(process, this, hash_table))
+ if (results == eExecutionCompleted)
{
- // Update the hash table signature
- m_hash_signature.UpdateSignature (hash_table);
+ // The result is the number of ClassInfo structures that were filled in
+ uint32_t num_class_infos = return_value.GetScalar().ULong();
+ if (log)
+ log->Printf("Discovered %u ObjC classes\n",num_class_infos);
+ if (num_class_infos > 0)
+ {
+ // Read the ClassInfo structures
+ DataBufferHeap buffer (num_class_infos * class_info_byte_size, 0);
+ if (process->ReadMemory(class_infos_addr, buffer.GetBytes(), buffer.GetByteSize(), err) == buffer.GetByteSize())
+ {
+ DataExtractor class_infos_data (buffer.GetBytes(),
+ buffer.GetByteSize(),
+ process->GetByteOrder(),
+ addr_size);
+ ParseClassInfoArray (class_infos_data, num_class_infos);
+ }
+ }
+ success = true;
+ }
+ else
+ {
+ if (log)
+ log->Printf("Error evaluating our find class name function: %s.\n", errors.GetData());
+ }
+ }
+ else
+ {
+ if (log)
+ log->Printf ("Error writing function arguments: \"%s\".", errors.GetData());
+ }
+
+ // Deallocate the memory we allocated for the ClassInfo array
+ process->DeallocateMemory(class_infos_addr);
+
+ return success;
+}
- lldb::LogSP log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS));
+void
+AppleObjCRuntimeV2::ParseClassInfoArray (const DataExtractor &data, uint32_t num_class_infos)
+{
+ // Parses an array of "num_class_infos" packed ClassInfo structures:
+ //
+ // struct ClassInfo
+ // {
+ // Class isa;
+ // uint32_t hash;
+ // } __attribute__((__packed__));
- uint32_t num_map_table_isas = 0;
- uint32_t num_objc_opt_ro_isas = 0;
+ Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS));
- ModuleSP objc_module_sp(GetObjCModule());
-
- if (objc_module_sp)
+ // Iterate through all ClassInfo structures
+ lldb::offset_t offset = 0;
+ for (uint32_t i=0; i<num_class_infos; ++i)
+ {
+ ObjCISA isa = data.GetPointer(&offset);
+
+ if (isa == 0)
+ {
+ if (log)
+ log->Printf("AppleObjCRuntimeV2 found NULL isa, ignoring this class info");
+ continue;
+ }
+ // Check if we already know about this ISA, if we do, the info will
+ // never change, so we can just skip it.
+ if (ISAIsCached(isa))
+ {
+ offset += 4;
+ }
+ else
+ {
+ // Read the 32 bit hash for the class name
+ const uint32_t name_hash = data.GetU32(&offset);
+ ClassDescriptorSP descriptor_sp (new ClassDescriptorV2(*this, isa, NULL));
+ AddClass (isa, descriptor_sp, name_hash);
+ if (log && log->GetVerbose())
+ log->Printf("AppleObjCRuntimeV2 added isa=0x%" PRIx64 ", hash=0x%8.8x", isa, name_hash);
+ }
+ }
+}
+
+bool
+AppleObjCRuntimeV2::UpdateISAToDescriptorMapSharedCache()
+{
+ Process *process = GetProcess();
+
+ if (process == NULL)
+ return false;
+
+ Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS));
+
+ ExecutionContext exe_ctx;
+
+ ThreadSP thread_sp = process->GetThreadList().GetSelectedThread();
+
+ if (!thread_sp)
+ return false;
+
+ thread_sp->CalculateExecutionContext(exe_ctx);
+ ClangASTContext *ast = process->GetTarget().GetScratchClangASTContext();
+
+ if (!ast)
+ return false;
+
+ Address function_address;
+
+ StreamString errors;
+
+ const uint32_t addr_size = process->GetAddressByteSize();
+
+ Error err;
+
+ const lldb::addr_t objc_opt_ptr = GetSharedCacheReadOnlyAddress();
+
+ if (objc_opt_ptr == LLDB_INVALID_ADDRESS)
+ return false;
+
+ // Read the total number of classes from the hash table
+ const uint32_t num_classes = 16*1024;
+ if (num_classes == 0)
+ {
+ if (log)
+ log->Printf ("No dynamic classes found in gdb_objc_realized_classes_addr.");
+ return false;
+ }
+
+ // Make some types for our arguments
+ clang_type_t clang_uint32_t_type = ast->GetBuiltinTypeForEncodingAndBitSize(eEncodingUint, 32);
+ clang_type_t clang_void_pointer_type = ast->CreatePointerType(ast->GetBuiltInType_void());
+
+ if (!m_get_shared_cache_class_info_code.get())
+ {
+ m_get_shared_cache_class_info_code.reset (new ClangUtilityFunction (g_get_shared_cache_class_info_body,
+ g_get_shared_cache_class_info_name));
+
+ errors.Clear();
+
+ if (!m_get_shared_cache_class_info_code->Install(errors, exe_ctx))
+ {
+ if (log)
+ log->Printf ("Failed to install implementation lookup: %s.", errors.GetData());
+ m_get_shared_cache_class_info_code.reset();
+ }
+ }
+
+ if (m_get_shared_cache_class_info_code.get())
+ function_address.SetOffset(m_get_shared_cache_class_info_code->StartAddress());
+ else
+ return false;
+
+ ValueList arguments;
+
+ // Next make the runner function for our implementation utility function.
+ if (!m_get_shared_cache_class_info_function.get())
+ {
+ Value value;
+ value.SetValueType (Value::eValueTypeScalar);
+ value.SetContext (Value::eContextTypeClangType, clang_void_pointer_type);
+ arguments.PushValue (value);
+
+ value.SetValueType (Value::eValueTypeScalar);
+ value.SetContext (Value::eContextTypeClangType, clang_void_pointer_type);
+ arguments.PushValue (value);
+
+ value.SetValueType (Value::eValueTypeScalar);
+ value.SetContext (Value::eContextTypeClangType, clang_uint32_t_type);
+ arguments.PushValue (value);
+
+ m_get_shared_cache_class_info_function.reset(new ClangFunction (*m_process,
+ ast,
+ clang_uint32_t_type,
+ function_address,
+ arguments));
+
+ if (m_get_shared_cache_class_info_function.get() == NULL)
+ return false;
+
+ errors.Clear();
+
+ unsigned num_errors = m_get_shared_cache_class_info_function->CompileFunction(errors);
+ if (num_errors)
+ {
+ if (log)
+ log->Printf ("Error compiling function: \"%s\".", errors.GetData());
+ return false;
+ }
+
+ errors.Clear();
+
+ if (!m_get_shared_cache_class_info_function->WriteFunctionWrapper(exe_ctx, errors))
+ {
+ if (log)
+ log->Printf ("Error Inserting function: \"%s\".", errors.GetData());
+ return false;
+ }
+ }
+ else
+ {
+ arguments = m_get_shared_cache_class_info_function->GetArgumentValues ();
+ }
+
+ const uint32_t class_info_byte_size = addr_size + 4;
+ const uint32_t class_infos_byte_size = num_classes * class_info_byte_size;
+ lldb::addr_t class_infos_addr = process->AllocateMemory (class_infos_byte_size,
+ ePermissionsReadable | ePermissionsWritable,
+ err);
+
+ if (class_infos_addr == LLDB_INVALID_ADDRESS)
+ return false;
+
+ Mutex::Locker locker(m_get_shared_cache_class_info_args_mutex);
+
+ // Fill in our function argument values
+ arguments.GetValueAtIndex(0)->GetScalar() = objc_opt_ptr;
+ arguments.GetValueAtIndex(1)->GetScalar() = class_infos_addr;
+ arguments.GetValueAtIndex(2)->GetScalar() = class_infos_byte_size;
+
+ bool success = false;
+
+ errors.Clear();
+
+ // Write our function arguments into the process so we can run our function
+ if (m_get_shared_cache_class_info_function->WriteFunctionArguments (exe_ctx,
+ m_get_shared_cache_class_info_args,
+ function_address,
+ arguments,
+ errors))
+ {
+ bool stop_others = true;
+ bool try_all_threads = false;
+ bool unwind_on_error = true;
+ bool ignore_breakpoints = true;
+
+ Value return_value;
+ return_value.SetValueType (Value::eValueTypeScalar);
+ return_value.SetContext (Value::eContextTypeClangType, clang_uint32_t_type);
+ return_value.GetScalar() = 0;
+
+ errors.Clear();
+
+ // Run the function
+ ExecutionResults results = m_get_shared_cache_class_info_function->ExecuteFunction (exe_ctx,
+ &m_get_shared_cache_class_info_args,
+ errors,
+ stop_others,
+ UTILITY_FUNCTION_TIMEOUT_USEC,
+ try_all_threads,
+ unwind_on_error,
+ ignore_breakpoints,
+ return_value);
+
+ if (results == eExecutionCompleted)
+ {
+ // The result is the number of ClassInfo structures that were filled in
+ uint32_t num_class_infos = return_value.GetScalar().ULong();
+ if (log)
+ log->Printf("Discovered %u ObjC classes in shared cache\n",num_class_infos);
+ if (num_class_infos > 0)
{
- for (RemoteNXMapTable::const_iterator it = hash_table.begin(); it != hash_table.end(); ++it)
+ // Read the ClassInfo structures
+ DataBufferHeap buffer (num_class_infos * class_info_byte_size, 0);
+ if (process->ReadMemory(class_infos_addr,
+ buffer.GetBytes(),
+ buffer.GetByteSize(),
+ err) == buffer.GetByteSize())
{
- RemoteNXMapTable::element elt = *it;
- ++num_map_table_isas;
-
- if (m_isa_to_descriptor_cache.count(elt.second))
- continue;
-
- ClassDescriptorSP descriptor_sp = ClassDescriptorSP(new ClassDescriptorV2(*this, elt.second, elt.first.AsCString()));
+ DataExtractor class_infos_data (buffer.GetBytes(),
+ buffer.GetByteSize(),
+ process->GetByteOrder(),
+ addr_size);
- if (log && log->GetVerbose())
- log->Printf("AppleObjCRuntimeV2 added (ObjCISA)0x%" PRIx64 " (%s) from dynamic table to isa->descriptor cache", elt.second, elt.first.AsCString());
-
- m_isa_to_descriptor_cache[elt.second] = descriptor_sp;
+ ParseClassInfoArray (class_infos_data, num_class_infos);
}
+ }
+ success = true;
+ }
+ else
+ {
+ if (log)
+ log->Printf("Error evaluating our find class name function: %s.\n", errors.GetData());
+ }
+ }
+ else
+ {
+ if (log)
+ log->Printf ("Error writing function arguments: \"%s\".", errors.GetData());
+ }
+
+ // Deallocate the memory we allocated for the ClassInfo array
+ process->DeallocateMemory(class_infos_addr);
+
+ return success;
+}
+
+
+bool
+AppleObjCRuntimeV2::UpdateISAToDescriptorMapFromMemory (RemoteNXMapTable &hash_table)
+{
+ Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS));
+
+ Process *process = GetProcess();
+
+ if (process == NULL)
+ return false;
+
+ uint32_t num_map_table_isas = 0;
+
+ ModuleSP objc_module_sp(GetObjCModule());
+
+ if (objc_module_sp)
+ {
+ for (RemoteNXMapTable::const_iterator it = hash_table.begin(); it != hash_table.end(); ++it)
+ {
+ RemoteNXMapTable::element elt = *it;
+ ++num_map_table_isas;
+
+ if (ISAIsCached(elt.second))
+ continue;
+
+ ClassDescriptorSP descriptor_sp = ClassDescriptorSP(new ClassDescriptorV2(*this, elt.second, elt.first.AsCString()));
+
+ if (log && log->GetVerbose())
+ log->Printf("AppleObjCRuntimeV2 added (ObjCISA)0x%" PRIx64 " (%s) from dynamic table to isa->descriptor cache", elt.second, elt.first.AsCString());
+
+ AddClass (elt.second, descriptor_sp, elt.first.AsCString());
+ }
+ }
+
+ return num_map_table_isas > 0;
+}
+
+lldb::addr_t
+AppleObjCRuntimeV2::GetSharedCacheReadOnlyAddress()
+{
+ Process *process = GetProcess();
+
+ if (process)
+ {
+ ModuleSP objc_module_sp(GetObjCModule());
+
+ if (objc_module_sp)
+ {
+ ObjectFile *objc_object = objc_module_sp->GetObjectFile();
+
+ if (objc_object)
+ {
+ SectionList *section_list = objc_object->GetSectionList();
- if (!m_loaded_objc_opt)
+ if (section_list)
{
- m_loaded_objc_opt = true;
-
- ObjectFile *objc_object = objc_module_sp->GetObjectFile();
+ SectionSP text_segment_sp (section_list->FindSectionByName(ConstString("__TEXT")));
- if (objc_object)
+ if (text_segment_sp)
{
- SectionList *section_list = objc_object->GetSectionList();
+ SectionSP objc_opt_section_sp (text_segment_sp->GetChildren().FindSectionByName(ConstString("__objc_opt_ro")));
- if (section_list)
+ if (objc_opt_section_sp)
{
- SectionSP text_segment_sp (section_list->FindSectionByName(ConstString("__TEXT")));
-
- if (text_segment_sp)
- {
- SectionSP objc_opt_section_sp (text_segment_sp->GetChildren().FindSectionByName(ConstString("__objc_opt_ro")));
-
- if (objc_opt_section_sp)
- {
- lldb::addr_t objc_opt_ptr = objc_opt_section_sp->GetLoadBaseAddress(&process->GetTarget());
-
- if (objc_opt_ptr != LLDB_INVALID_ADDRESS)
- {
- RemoteObjCOpt objc_opt(process, objc_opt_ptr);
-
- for (RemoteObjCOpt::const_iterator it = objc_opt.begin(); it != objc_opt.end(); ++it)
- {
- ObjCLanguageRuntime::ObjCISA objc_isa = *it;
- ++num_objc_opt_ro_isas;
- if (m_isa_to_descriptor_cache.count(objc_isa))
- continue;
-
- ClassDescriptorSP descriptor_sp = ClassDescriptorSP(new ClassDescriptorV2(*this, objc_isa, NULL));
-
- if (log && log->GetVerbose())
- log->Printf("AppleObjCRuntimeV2 added (ObjCISA)0x%" PRIx64 " (%s) from static table to isa->descriptor cache", objc_isa, descriptor_sp->GetClassName().AsCString());
-
- m_isa_to_descriptor_cache[objc_isa] = descriptor_sp;
- }
- }
- }
- }
+ return objc_opt_section_sp->GetLoadBaseAddress(&process->GetTarget());
}
}
}
}
}
}
+ return LLDB_INVALID_ADDRESS;
+}
+
+void
+AppleObjCRuntimeV2::UpdateISAToDescriptorMapIfNeeded()
+{
+ Timer scoped_timer (__PRETTY_FUNCTION__, __PRETTY_FUNCTION__);
+
+ // Else we need to check with our process to see when the map was updated.
+ Process *process = GetProcess();
+
+ if (process)
+ {
+ RemoteNXMapTable hash_table;
+
+ // Update the process stop ID that indicates the last time we updated the
+ // map, wether it was successful or not.
+ m_isa_to_descriptor_stop_id = process->GetStopID();
+
+ if (!m_hash_signature.NeedsUpdate(process, this, hash_table))
+ return;
+
+ m_hash_signature.UpdateSignature (hash_table);
+
+ // Grab the dynamicly loaded objc classes from the hash table in memory
+ UpdateISAToDescriptorMapDynamic(hash_table);
+
+ // Now get the objc classes that are baked into the Objective C runtime
+ // in the shared cache, but only once per process as this data never
+ // changes
+ if (!m_loaded_objc_opt)
+ UpdateISAToDescriptorMapSharedCache();
+ }
else
{
- m_isa_to_descriptor_cache_stop_id = UINT32_MAX;
+ m_isa_to_descriptor_stop_id = UINT32_MAX;
}
}
Modified: lldb/branches/windows/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV2.h
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/windows/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV2.h?rev=179679&r1=179678&r2=179679&view=diff
==============================================================================
--- lldb/branches/windows/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV2.h (original)
+++ lldb/branches/windows/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV2.h Wed Apr 17 03:38:48 2013
@@ -83,7 +83,6 @@ public:
// we report an actual type - otherwise, we just say tagged
// there is no connection between the values here and the tagged pointers map
static const ObjCLanguageRuntime::ObjCISA g_objc_Tagged_ISA = 1;
-
static const ObjCLanguageRuntime::ObjCISA g_objc_Tagged_ISA_NSAtom = 2;
static const ObjCLanguageRuntime::ObjCISA g_objc_Tagged_ISA_NSNumber = 3;
static const ObjCLanguageRuntime::ObjCISA g_objc_Tagged_ISA_NSDateTS = 4;
@@ -135,20 +134,38 @@ private:
lldb::addr_t
GetISAHashTablePointer ();
- bool RunFunctionToFindClassName (lldb::addr_t class_addr, Thread *thread, char *name_dst, size_t max_name_len);
+ bool
+ UpdateISAToDescriptorMapFromMemory (RemoteNXMapTable &hash_table);
+
+ bool
+ UpdateISAToDescriptorMapDynamic(RemoteNXMapTable &hash_table);
+
+ void
+ ParseClassInfoArray (const lldb_private::DataExtractor &data,
+ uint32_t num_class_infos);
+
+ bool
+ UpdateISAToDescriptorMapSharedCache ();
+
+ lldb::addr_t
+ GetSharedCacheReadOnlyAddress();
- std::auto_ptr<ClangFunction> m_get_class_name_function;
- std::auto_ptr<ClangUtilityFunction> m_get_class_name_code;
- lldb::addr_t m_get_class_name_args;
- Mutex m_get_class_name_args_mutex;
+ std::auto_ptr<ClangFunction> m_get_class_info_function;
+ std::auto_ptr<ClangUtilityFunction> m_get_class_info_code;
+ lldb::addr_t m_get_class_info_args;
+ Mutex m_get_class_info_args_mutex;
+
+ std::auto_ptr<ClangFunction> m_get_shared_cache_class_info_function;
+ std::auto_ptr<ClangUtilityFunction> m_get_shared_cache_class_info_code;
+ lldb::addr_t m_get_shared_cache_class_info_args;
+ Mutex m_get_shared_cache_class_info_args_mutex;
+
std::auto_ptr<TypeVendor> m_type_vendor_ap;
lldb::addr_t m_isa_hash_table_ptr;
HashTableSignature m_hash_signature;
bool m_has_object_getClass;
bool m_loaded_objc_opt;
- static const char *g_find_class_name_function_name;
- static const char *g_find_class_name_function_body;
};
} // namespace lldb_private
Modified: lldb/branches/windows/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCTrampolineHandler.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/windows/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCTrampolineHandler.cpp?rev=179679&r1=179678&r2=179679&view=diff
==============================================================================
--- lldb/branches/windows/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCTrampolineHandler.cpp (original)
+++ lldb/branches/windows/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCTrampolineHandler.cpp Wed Apr 17 03:38:48 2013
@@ -43,7 +43,8 @@ using namespace lldb;
using namespace lldb_private;
const char *AppleObjCTrampolineHandler::g_lookup_implementation_function_name = "__lldb_objc_find_implementation_for_selector";
-const char *AppleObjCTrampolineHandler::g_lookup_implementation_function_code = " \n\
+const char *AppleObjCTrampolineHandler::g_lookup_implementation_function_code = NULL;
+const char *AppleObjCTrampolineHandler::g_lookup_implementation_with_stret_function_code = " \n\
extern \"C\" \n\
{ \n\
extern void *class_getMethodImplementation(void *objc_class, void *sel); \n\
@@ -152,6 +153,106 @@ extern \"C\" void * __lldb_objc_find_imp
return return_struct.impl_addr; \n\
} \n\
";
+const char *AppleObjCTrampolineHandler::g_lookup_implementation_no_stret_function_code = " \n\
+extern \"C\" \n\
+{ \n\
+ extern void *class_getMethodImplementation(void *objc_class, void *sel); \n\
+ extern void * sel_getUid(char *name); \n\
+ extern int printf(const char *format, ...); \n\
+} \n\
+extern \"C\" void * __lldb_objc_find_implementation_for_selector (void *object, \n\
+ void *sel, \n\
+ int is_stret, \n\
+ int is_super, \n\
+ int is_super2, \n\
+ int is_fixup, \n\
+ int is_fixed, \n\
+ int debug) \n\
+{ \n\
+ struct __lldb_imp_return_struct \n\
+ { \n\
+ void *class_addr; \n\
+ void *sel_addr; \n\
+ void *impl_addr; \n\
+ }; \n\
+ \n\
+ struct __lldb_objc_class { \n\
+ void *isa; \n\
+ void *super_ptr; \n\
+ }; \n\
+ struct __lldb_objc_super { \n\
+ void *reciever; \n\
+ struct __lldb_objc_class *class_ptr; \n\
+ }; \n\
+ struct __lldb_msg_ref { \n\
+ void *dont_know; \n\
+ void *sel; \n\
+ }; \n\
+ \n\
+ struct __lldb_imp_return_struct return_struct; \n\
+ \n\
+ if (debug) \n\
+ printf (\"\\n*** Called with obj: 0x%p sel: 0x%p is_stret: %d is_super: %d, \" \n\
+ \"is_super2: %d, is_fixup: %d, is_fixed: %d\\n\", \n\
+ object, sel, is_stret, is_super, is_super2, is_fixup, is_fixed); \n\
+ if (is_super) \n\
+ { \n\
+ if (is_super2) \n\
+ { \n\
+ return_struct.class_addr = ((__lldb_objc_super *) object)->class_ptr->super_ptr; \n\
+ } \n\
+ else \n\
+ { \n\
+ return_struct.class_addr = ((__lldb_objc_super *) object)->class_ptr; \n\
+ } \n\
+ } \n\
+ else \n\
+ { \n\
+ void *class_ptr = (void *) [(id) object class]; \n\
+ if (class_ptr == object) \n\
+ { \n\
+ struct __lldb_objc_class *class_as_class_struct = (struct __lldb_objc_class *) class_ptr; \n\
+ if (debug) \n\
+ printf (\"Found a class object, need to return the meta class 0x%p -> 0x%p\\n\", \n\
+ class_ptr, class_as_class_struct->isa); \n\
+ return_struct.class_addr = class_as_class_struct->isa; \n\
+ } \n\
+ else \n\
+ { \n\
+ if (debug) \n\
+ printf (\"[object class] returned: 0x%p.\\n\", class_ptr); \n\
+ return_struct.class_addr = class_ptr; \n\
+ } \n\
+ } \n\
+ \n\
+ if (is_fixup) \n\
+ { \n\
+ if (is_fixed) \n\
+ { \n\
+ return_struct.sel_addr = ((__lldb_msg_ref *) sel)->sel; \n\
+ } \n\
+ else \n\
+ { \n\
+ char *sel_name = (char *) ((__lldb_msg_ref *) sel)->sel; \n\
+ return_struct.sel_addr = sel_getUid (sel_name); \n\
+ if (debug) \n\
+ printf (\"\\n*** Got fixed up selector: 0x%p for name %s.\\n\", \n\
+ return_struct.sel_addr, sel_name); \n\
+ } \n\
+ } \n\
+ else \n\
+ { \n\
+ return_struct.sel_addr = sel; \n\
+ } \n\
+ \n\
+ return_struct.impl_addr = class_getMethodImplementation (return_struct.class_addr, \n\
+ return_struct.sel_addr); \n\
+ if (debug) \n\
+ printf (\"\\n*** Returning implementation: 0x%p.\\n\", return_struct.impl_addr); \n\
+ \n\
+ return return_struct.impl_addr; \n\
+} \n\
+";
AppleObjCTrampolineHandler::AppleObjCVTables::VTableRegion::VTableRegion(AppleObjCVTables *owner, lldb::addr_t header_addr) :
m_valid (true),
@@ -194,12 +295,12 @@ AppleObjCTrampolineHandler::AppleObjCVTa
return;
}
- uint32_t offset_ptr = 0;
- const uint16_t header_size = data.GetU16(&offset_ptr);
- const uint16_t descriptor_size = data.GetU16(&offset_ptr);
- const size_t num_descriptors = data.GetU32(&offset_ptr);
+ lldb::offset_t offset = 0;
+ const uint16_t header_size = data.GetU16(&offset);
+ const uint16_t descriptor_size = data.GetU16(&offset);
+ const size_t num_descriptors = data.GetU32(&offset);
- m_next_region = data.GetPointer(&offset_ptr);
+ m_next_region = data.GetPointer(&offset);
// If the header size is 0, that means we've come in too early before this data is set up.
// Set ourselves as not valid, and continue.
@@ -239,16 +340,16 @@ AppleObjCTrampolineHandler::AppleObjCVTa
// The actual code for the vtables will be laid out consecutively, so I also
// compute the start and end of the whole code block.
- offset_ptr = 0;
+ offset = 0;
m_code_start_addr = 0;
m_code_end_addr = 0;
for (int i = 0; i < num_descriptors; i++)
{
- lldb::addr_t start_offset = offset_ptr;
- uint32_t offset = desc_extractor.GetU32 (&offset_ptr);
- uint32_t flags = desc_extractor.GetU32 (&offset_ptr);
- lldb::addr_t code_addr = desc_ptr + start_offset + offset;
+ lldb::addr_t start_offset = offset;
+ uint32_t voffset = desc_extractor.GetU32 (&offset);
+ uint32_t flags = desc_extractor.GetU32 (&offset);
+ lldb::addr_t code_addr = desc_ptr + start_offset + voffset;
m_descriptors.push_back (VTableDescriptor(flags, code_addr));
if (m_code_start_addr == 0 || code_addr < m_code_start_addr)
@@ -256,7 +357,7 @@ AppleObjCTrampolineHandler::AppleObjCVTa
if (code_addr > m_code_end_addr)
m_code_end_addr = code_addr;
- offset_ptr = start_offset + descriptor_size;
+ offset = start_offset + descriptor_size;
}
// Finally, a little bird told me that all the vtable code blocks are the same size.
// Let's compute the blocks and if they are all the same add the size to the code end address:
@@ -382,6 +483,7 @@ AppleObjCTrampolineHandler::AppleObjCVTa
{
m_trampolines_changed_bp_id = trampolines_changed_bp_sp->GetID();
trampolines_changed_bp_sp->SetCallback (RefreshTrampolines, this, true);
+ trampolines_changed_bp_sp->SetBreakpointKind ("objc-trampolines-changed");
return true;
}
}
@@ -427,8 +529,8 @@ AppleObjCTrampolineHandler::AppleObjCVTa
data,
0,
NULL);
- uint32_t offset_ptr = 0;
- lldb::addr_t region_addr = data.GetPointer(&offset_ptr);
+ lldb::offset_t offset = 0;
+ lldb::addr_t region_addr = data.GetPointer(&offset);
if (region_addr != 0)
vtable_handler->ReadRegions(region_addr);
@@ -458,7 +560,7 @@ AppleObjCTrampolineHandler::AppleObjCVTa
if (!m_process_sp)
return false;
- LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP));
+ Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP));
// We aren't starting at the trampoline symbol.
InitializeVTableSymbols ();
@@ -555,8 +657,26 @@ AppleObjCTrampolineHandler::AppleObjCTra
m_msg_forward_stret_addr = msg_forward_stret->GetAddress().GetOpcodeLoadAddress(target);
// FIXME: Do some kind of logging here.
- if (m_impl_fn_addr == LLDB_INVALID_ADDRESS || m_impl_stret_fn_addr == LLDB_INVALID_ADDRESS)
+ if (m_impl_fn_addr == LLDB_INVALID_ADDRESS)
+ {
+ // If we can't even find the ordinary get method implementation function, then we aren't going to be able to
+ // step through any method dispatches. Warn to that effect and get out of here.
+ process_sp->GetTarget().GetDebugger().GetErrorStream().Printf("Could not find implementation lookup function \"%s\""
+ " step in through ObjC method dispatch will not work.\n",
+ get_impl_name.AsCString());
return;
+ }
+ else if (m_impl_stret_fn_addr == LLDB_INVALID_ADDRESS)
+ {
+ // It there is no stret return lookup function, assume that it is the same as the straight lookup:
+ m_impl_stret_fn_addr = m_impl_fn_addr;
+ // Also we will use the version of the lookup code that doesn't rely on the stret version of the function.
+ g_lookup_implementation_function_code = g_lookup_implementation_no_stret_function_code;
+ }
+ else
+ {
+ g_lookup_implementation_function_code = g_lookup_implementation_with_stret_function_code;
+ }
// Look up the addresses for the objc dispatch functions and cache them. For now I'm inspecting the symbol
// names dynamically to figure out how to dispatch to them. If it becomes more complicated than this we can
@@ -591,7 +711,7 @@ AppleObjCTrampolineHandler::SetupDispatc
ExecutionContext exe_ctx (thread.shared_from_this());
Address impl_code_address;
StreamString errors;
- LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP));
+ Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP));
lldb::addr_t args_addr = LLDB_INVALID_ADDRESS;
// Scope for mutex locker:
@@ -628,15 +748,26 @@ AppleObjCTrampolineHandler::SetupDispatc
}
else if (!m_impl_code.get())
{
- m_impl_code.reset (new ClangUtilityFunction (g_lookup_implementation_function_code,
- g_lookup_implementation_function_name));
- if (!m_impl_code->Install(errors, exe_ctx))
+ if (g_lookup_implementation_function_code != NULL)
+ {
+ m_impl_code.reset (new ClangUtilityFunction (g_lookup_implementation_function_code,
+ g_lookup_implementation_function_name));
+ if (!m_impl_code->Install(errors, exe_ctx))
+ {
+ if (log)
+ log->Printf ("Failed to install implementation lookup: %s.", errors.GetData());
+ m_impl_code.reset();
+ return args_addr;
+ }
+ }
+ else
{
if (log)
- log->Printf ("Failed to install implementation lookup: %s.", errors.GetData());
- m_impl_code.reset();
- return args_addr;
+ log->Printf("No method lookup implementation code.");
+ errors.Printf ("No method lookup implementation code found.");
+ return LLDB_INVALID_ADDRESS;
}
+
impl_code_address.Clear();
impl_code_address.SetOffset(m_impl_code->StartAddress());
}
@@ -734,7 +865,7 @@ AppleObjCTrampolineHandler::GetStepThrou
if (found_it)
{
- LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP));
+ Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP));
// We are decoding a method dispatch.
// First job is to pull the arguments out:
@@ -975,12 +1106,16 @@ AppleObjCTrampolineHandler::GetStepThrou
flag_value.GetScalar() = 0; // FIXME - Set to 0 when debugging is done.
dispatch_values.PushValue (flag_value);
+
+ // The step through code might have to fill in the cache, so it is not safe to run only one thread.
+ // So we override the stop_others value passed in to us here:
+ const bool trampoline_stop_others = false;
ret_plan_sp.reset (new AppleThreadPlanStepThroughObjCTrampoline (thread,
this,
dispatch_values,
isa_addr,
sel_addr,
- stop_others));
+ trampoline_stop_others));
if (log)
{
StreamString s;
Modified: lldb/branches/windows/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCTrampolineHandler.h
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/windows/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCTrampolineHandler.h?rev=179679&r1=179678&r2=179679&view=diff
==============================================================================
--- lldb/branches/windows/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCTrampolineHandler.h (original)
+++ lldb/branches/windows/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCTrampolineHandler.h Wed Apr 17 03:38:48 2013
@@ -67,6 +67,8 @@ public:
private:
static const char *g_lookup_implementation_function_name;
static const char *g_lookup_implementation_function_code;
+ static const char *g_lookup_implementation_with_stret_function_code;
+ static const char *g_lookup_implementation_no_stret_function_code;
class AppleObjCVTables
{
Modified: lldb/branches/windows/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCTypeVendor.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/windows/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCTypeVendor.cpp?rev=179679&r1=179678&r2=179679&view=diff
==============================================================================
--- lldb/branches/windows/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCTypeVendor.cpp (original)
+++ lldb/branches/windows/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCTypeVendor.cpp Wed Apr 17 03:38:48 2013
@@ -30,14 +30,14 @@ public:
{
}
- clang::DeclContextLookupResult
+ bool
FindExternalVisibleDeclsByName (const clang::DeclContext *decl_ctx,
clang::DeclarationName name)
{
static unsigned int invocation_id = 0;
unsigned int current_id = invocation_id++;
- lldb::LogSP log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS)); // FIXME - a more appropriate log channel?
+ Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS)); // FIXME - a more appropriate log channel?
if (log)
{
@@ -60,12 +60,15 @@ public:
if (!m_type_vendor.FinishDecl(non_const_interface_decl))
break;
-
- return non_const_interface_decl->lookup(name);
+
+ clang::DeclContext::lookup_const_result result = non_const_interface_decl->lookup(name);
+
+ return (result.size() != 0);
}
while(0);
- return clang::DeclContextLookupResult();
+ SetNoExternalVisibleDeclsForName(decl_ctx, name);
+ return false;
}
clang::ExternalLoadResult
@@ -82,7 +85,7 @@ public:
static unsigned int invocation_id = 0;
unsigned int current_id = invocation_id++;
- lldb::LogSP log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS)); // FIXME - a more appropriate log channel?
+ Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS)); // FIXME - a more appropriate log channel?
if (log)
{
@@ -112,7 +115,7 @@ public:
static unsigned int invocation_id = 0;
unsigned int current_id = invocation_id++;
- lldb::LogSP log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS)); // FIXME - a more appropriate log channel?
+ Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS)); // FIXME - a more appropriate log channel?
if (log)
{
@@ -195,8 +198,8 @@ AppleObjCTypeVendor::GetDeclForISA(ObjCL
NULL);
ClangASTMetadata meta_data;
- meta_data.SetISAPtr((uint64_t) isa);
- m_external_source->SetMetadata((uintptr_t)new_iface_decl, meta_data);
+ meta_data.SetISAPtr(isa);
+ m_external_source->SetMetadata(new_iface_decl, meta_data);
new_iface_decl->setHasExternalVisibleStorage();
new_iface_decl->setHasExternalLexicalStorage();
@@ -323,8 +326,6 @@ public:
clang::ObjCMethodDecl *BuildMethod (clang::ObjCInterfaceDecl *interface_decl, const char *name, bool instance)
{
- lldb::LogSP log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS)); // FIXME - a more appropriate log channel?
-
if (!m_is_valid || m_type_vector.size() < 3)
return NULL;
@@ -402,7 +403,6 @@ public:
arg_type,
NULL,
clang::SC_None,
- clang::SC_None,
NULL));
}
@@ -495,9 +495,9 @@ private:
bool
AppleObjCTypeVendor::FinishDecl(clang::ObjCInterfaceDecl *interface_decl)
{
- lldb::LogSP log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS)); // FIXME - a more appropriate log channel?
+ Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS)); // FIXME - a more appropriate log channel?
- ClangASTMetadata *metadata = m_external_source->GetMetadata((uintptr_t)interface_decl);
+ ClangASTMetadata *metadata = m_external_source->GetMetadata(interface_decl);
ObjCLanguageRuntime::ObjCISA objc_isa = 0;
if (metadata)
objc_isa = metadata->GetISAPtr();
@@ -591,7 +591,7 @@ AppleObjCTypeVendor::FindTypes (const Co
static unsigned int invocation_id = 0;
unsigned int current_id = invocation_id++;
- lldb::LogSP log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS)); // FIXME - a more appropriate log channel?
+ Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_EXPRESSIONS)); // FIXME - a more appropriate log channel?
if (log)
log->Printf("AppleObjCTypeVendor::FindTypes [%u] ('%s', %s, %u, )",
@@ -627,7 +627,7 @@ AppleObjCTypeVendor::FindTypes (const Co
ASTDumper dumper(result_iface_type);
uint64_t isa_value = LLDB_INVALID_ADDRESS;
- ClangASTMetadata *metadata = m_external_source->GetMetadata((uintptr_t)result_iface_decl);
+ ClangASTMetadata *metadata = m_external_source->GetMetadata(result_iface_decl);
if (metadata)
isa_value = metadata->GetISAPtr();
Modified: lldb/branches/windows/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleThreadPlanStepThroughObjCTrampoline.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/windows/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleThreadPlanStepThroughObjCTrampoline.cpp?rev=179679&r1=179678&r2=179679&view=diff
==============================================================================
--- lldb/branches/windows/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleThreadPlanStepThroughObjCTrampoline.cpp (original)
+++ lldb/branches/windows/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleThreadPlanStepThroughObjCTrampoline.cpp Wed Apr 17 03:38:48 2013
@@ -84,8 +84,15 @@ AppleThreadPlanStepThroughObjCTrampoline
}
m_impl_function = m_trampoline_handler->GetLookupImplementationWrapperFunction();
ExecutionContext exc_ctx;
+ const bool unwind_on_error = true;
+ const bool ignore_breakpoints = true;
m_thread.CalculateExecutionContext(exc_ctx);
- m_func_sp.reset(m_impl_function->GetThreadPlanToCallFunction (exc_ctx, m_args_addr, errors, m_stop_others));
+ m_func_sp.reset(m_impl_function->GetThreadPlanToCallFunction (exc_ctx,
+ m_args_addr,
+ errors,
+ m_stop_others,
+ unwind_on_error,
+ ignore_breakpoints));
m_func_sp->SetOkayToDiscard(true);
m_thread.QueueThreadPlan (m_func_sp, false);
}
@@ -119,7 +126,7 @@ AppleThreadPlanStepThroughObjCTrampoline
}
bool
-AppleThreadPlanStepThroughObjCTrampoline::PlanExplainsStop ()
+AppleThreadPlanStepThroughObjCTrampoline::PlanExplainsStop (Event *event_ptr)
{
// If we get asked to explain the stop it will be because something went
// wrong (like the implementation for selector function crashed... We're going
@@ -166,7 +173,7 @@ AppleThreadPlanStepThroughObjCTrampoline
lldb::addr_t target_addr = target_addr_value.GetScalar().ULongLong();
Address target_so_addr;
target_so_addr.SetOpcodeLoadAddress(target_addr, exc_ctx.GetTargetPtr());
- LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP));
+ Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP));
if (target_addr == 0)
{
if (log)
Modified: lldb/branches/windows/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleThreadPlanStepThroughObjCTrampoline.h
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/windows/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleThreadPlanStepThroughObjCTrampoline.h?rev=179679&r1=179678&r2=179679&view=diff
==============================================================================
--- lldb/branches/windows/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleThreadPlanStepThroughObjCTrampoline.h (original)
+++ lldb/branches/windows/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleThreadPlanStepThroughObjCTrampoline.h Wed Apr 17 03:38:48 2013
@@ -46,7 +46,7 @@ public:
ValidatePlan (Stream *error);
virtual bool
- PlanExplainsStop ();
+ PlanExplainsStop (Event *event_ptr);
virtual lldb::StateType
@@ -54,6 +54,12 @@ public:
virtual bool
ShouldStop (Event *event_ptr);
+
+ virtual bool
+ StopOthers()
+ {
+ return m_stop_others;
+ }
// The base class MischiefManaged does some cleanup - so you have to call it
// in your MischiefManaged derived class.
Modified: lldb/branches/windows/source/Plugins/ObjectContainer/BSD-Archive/ObjectContainerBSDArchive.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/windows/source/Plugins/ObjectContainer/BSD-Archive/ObjectContainerBSDArchive.cpp?rev=179679&r1=179678&r2=179679&view=diff
==============================================================================
--- lldb/branches/windows/source/Plugins/ObjectContainer/BSD-Archive/ObjectContainerBSDArchive.cpp (original)
+++ lldb/branches/windows/source/Plugins/ObjectContainer/BSD-Archive/ObjectContainerBSDArchive.cpp Wed Apr 17 03:38:48 2013
@@ -65,8 +65,8 @@ ObjectContainerBSDArchive::Object::Clear
ar_file_size = 0;
}
-uint32_t
-ObjectContainerBSDArchive::Object::Extract (const DataExtractor& data, uint32_t offset)
+lldb::offset_t
+ObjectContainerBSDArchive::Object::Extract (const DataExtractor& data, lldb::offset_t offset)
{
size_t ar_name_len = 0;
std::string str;
@@ -114,17 +114,19 @@ ObjectContainerBSDArchive::Object::Extra
ar_file_size = ar_size - ar_name_len;
return offset;
}
- return LLDB_INVALID_INDEX32;
+ return LLDB_INVALID_OFFSET;
}
ObjectContainerBSDArchive::Archive::Archive
(
const lldb_private::ArchSpec &arch,
- const lldb_private::TimeValue &time
+ const lldb_private::TimeValue &time,
+ lldb_private::DataExtractor &data
) :
m_arch (arch),
m_time (time),
- m_objects()
+ m_objects(),
+ m_data (data)
{
}
@@ -133,10 +135,11 @@ ObjectContainerBSDArchive::Archive::~Arc
}
size_t
-ObjectContainerBSDArchive::Archive::ParseObjects (DataExtractor &data)
+ObjectContainerBSDArchive::Archive::ParseObjects ()
{
+ DataExtractor &data = m_data;
std::string str;
- uint32_t offset = 0;
+ lldb::offset_t offset = 0;
str.assign((const char *)data.GetData(&offset, SARMAG), SARMAG);
if (str == ARMAG)
{
@@ -144,9 +147,9 @@ ObjectContainerBSDArchive::Archive::Pars
do
{
offset = obj.Extract (data, offset);
- if (offset == LLDB_INVALID_INDEX32)
+ if (offset == LLDB_INVALID_OFFSET)
break;
- uint32_t obj_idx = m_objects.size();
+ size_t obj_idx = m_objects.size();
m_objects.push_back(obj);
// Insert all of the C strings out of order for now...
m_object_name_to_index_map.Append (obj.ar_name.GetCString(), obj_idx);
@@ -163,7 +166,7 @@ ObjectContainerBSDArchive::Archive::Pars
ObjectContainerBSDArchive::Object *
ObjectContainerBSDArchive::Archive::FindObject (const ConstString &object_name)
{
- const UniqueCStringMap<uint32_t>::Entry *match = m_object_name_to_index_map.FindFirstValueForName (object_name.GetCString());
+ const ObjectNameToIndexMap::Entry *match = m_object_name_to_index_map.FindFirstValueForName (object_name.GetCString());
if (match)
return &m_objects[match->value];
return NULL;
@@ -216,10 +219,10 @@ ObjectContainerBSDArchive::Archive::Pars
DataExtractor &data
)
{
- shared_ptr archive_sp(new Archive (arch, time));
+ shared_ptr archive_sp(new Archive (arch, time, data));
if (archive_sp)
{
- if (archive_sp->ParseObjects (data) > 0)
+ if (archive_sp->ParseObjects () > 0)
{
Mutex::Locker locker(Archive::GetArchiveCacheMutex ());
Archive::GetArchiveCache().insert(std::make_pair(file, archive_sp));
@@ -280,23 +283,41 @@ ObjectContainerBSDArchive::CreateInstanc
(
const lldb::ModuleSP &module_sp,
DataBufferSP& data_sp,
+ lldb::offset_t data_offset,
const FileSpec *file,
- addr_t offset,
- addr_t length)
+ lldb::offset_t file_offset,
+ lldb::offset_t length)
{
+ ConstString object_name (module_sp->GetObjectName());
+ if (object_name)
+ {
+ if (data_sp)
+ {
+ // We have data, which means this is the first 512 bytes of the file
+ // Check to see if the magic bytes match and if they do, read the entire
+ // table of contents for the archive and cache it
DataExtractor data;
- data.SetData (data_sp, offset, length);
+ data.SetData (data_sp, data_offset, length);
if (file && data_sp && ObjectContainerBSDArchive::MagicBytesMatch(data))
{
Timer scoped_timer (__PRETTY_FUNCTION__,
"ObjectContainerBSDArchive::CreateInstance (module = %s/%s, file = %p, file_offset = 0x%8.8" PRIx64 ", file_size = 0x%8.8" PRIx64 ")",
module_sp->GetFileSpec().GetDirectory().AsCString(),
module_sp->GetFileSpec().GetFilename().AsCString(),
- file, (uint64_t) offset, (uint64_t) length);
+ file, (uint64_t) file_offset, (uint64_t) length);
- Archive::shared_ptr archive_sp (Archive::FindCachedArchive (*file, module_sp->GetArchitecture(), module_sp->GetModificationTime()));
+ // Map the entire .a file to be sure that we don't lose any data if the file
+ // gets updated by a new build while this .a file is being used for debugging
+ DataBufferSP archive_data_sp (file->MemoryMapFileContents(file_offset, length));
+ lldb::offset_t archive_data_offset = 0;
- std::auto_ptr<ObjectContainerBSDArchive> container_ap(new ObjectContainerBSDArchive (module_sp, data_sp, file, offset, length));
+ Archive::shared_ptr archive_sp (Archive::FindCachedArchive (*file, module_sp->GetArchitecture(), module_sp->GetModificationTime()));
+ std::auto_ptr<ObjectContainerBSDArchive> container_ap(new ObjectContainerBSDArchive (module_sp,
+ archive_data_sp,
+ archive_data_offset,
+ file,
+ file_offset,
+ length));
if (container_ap.get())
{
@@ -310,6 +331,24 @@ ObjectContainerBSDArchive::CreateInstanc
return container_ap.release();
}
}
+ }
+ else
+ {
+ // No data, just check for a cached archive
+ Archive::shared_ptr archive_sp (Archive::FindCachedArchive (*file, module_sp->GetArchitecture(), module_sp->GetModificationTime()));
+ if (archive_sp)
+ {
+ std::auto_ptr<ObjectContainerBSDArchive> container_ap(new ObjectContainerBSDArchive (module_sp, data_sp, data_offset, file, file_offset, length));
+
+ if (container_ap.get())
+ {
+ // We already have this archive in our cache, use it
+ container_ap->SetArchive (archive_sp);
+ return container_ap.release();
+ }
+ }
+ }
+ }
return NULL;
}
@@ -332,12 +371,13 @@ ObjectContainerBSDArchive::MagicBytesMat
ObjectContainerBSDArchive::ObjectContainerBSDArchive
(
const lldb::ModuleSP &module_sp,
- DataBufferSP& dataSP,
+ DataBufferSP& data_sp,
+ lldb::offset_t data_offset,
const lldb_private::FileSpec *file,
- lldb::addr_t offset,
- lldb::addr_t size
+ lldb::offset_t file_offset,
+ lldb::offset_t size
) :
- ObjectContainer (module_sp, file, offset, size, dataSP),
+ ObjectContainer (module_sp, file, file_offset, size, data_sp, data_offset),
m_archive_sp ()
{
}
@@ -368,6 +408,9 @@ ObjectContainerBSDArchive::ParseHeader (
module_sp->GetModificationTime(),
m_data);
}
+ // Clear the m_data that contains the entire archive
+ // data and let our m_archive_sp hold onto the data.
+ m_data.Clear();
}
}
return m_archive_sp.get() != NULL;
@@ -409,13 +452,17 @@ ObjectContainerBSDArchive::GetObjectFile
{
Object *object = m_archive_sp->FindObject (module_sp->GetObjectName());
if (object)
- return ObjectFile::FindPlugin (module_sp,
+ {
+ lldb::offset_t data_offset = m_offset + object->ar_file_offset;
+ return ObjectFile::FindPlugin (module_sp,
file,
m_offset + object->ar_file_offset,
- object->ar_file_size,
- m_data.GetSharedDataBuffer());
+ object->ar_file_size,
+ m_archive_sp->GetData().GetSharedDataBuffer(),
+ data_offset);
}
}
+ }
return ObjectFileSP();
}
Modified: lldb/branches/windows/source/Plugins/ObjectContainer/BSD-Archive/ObjectContainerBSDArchive.h
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/windows/source/Plugins/ObjectContainer/BSD-Archive/ObjectContainerBSDArchive.h?rev=179679&r1=179678&r2=179679&view=diff
==============================================================================
--- lldb/branches/windows/source/Plugins/ObjectContainer/BSD-Archive/ObjectContainerBSDArchive.h (original)
+++ lldb/branches/windows/source/Plugins/ObjectContainer/BSD-Archive/ObjectContainerBSDArchive.h Wed Apr 17 03:38:48 2013
@@ -40,10 +40,11 @@ public:
static lldb_private::ObjectContainer *
CreateInstance (const lldb::ModuleSP &module_sp,
- lldb::DataBufferSP& dataSP,
+ lldb::DataBufferSP& data_sp,
+ lldb::offset_t data_offset,
const lldb_private::FileSpec *file,
- lldb::addr_t offset,
- lldb::addr_t length);
+ lldb::offset_t offset,
+ lldb::offset_t length);
static bool
MagicBytesMatch (const lldb_private::DataExtractor &data);
@@ -52,10 +53,11 @@ public:
// Member Functions
//------------------------------------------------------------------
ObjectContainerBSDArchive (const lldb::ModuleSP &module_sp,
- lldb::DataBufferSP& dataSP,
+ lldb::DataBufferSP& data_sp,
+ lldb::offset_t data_offset,
const lldb_private::FileSpec *file,
- lldb::addr_t offset,
- lldb::addr_t length);
+ lldb::offset_t offset,
+ lldb::offset_t length);
virtual
~ObjectContainerBSDArchive();
@@ -97,8 +99,8 @@ protected:
void
Clear();
- uint32_t
- Extract (const lldb_private::DataExtractor& data, uint32_t offset);
+ lldb::offset_t
+ Extract (const lldb_private::DataExtractor& data, lldb::offset_t offset);
lldb_private::ConstString ar_name; // name
uint32_t ar_date; // modification time
@@ -106,8 +108,8 @@ protected:
uint16_t ar_gid; // group id
uint16_t ar_mode; // octal file permissions
uint32_t ar_size; // size in bytes
- uint32_t ar_file_offset; // file offset in bytes from the beginning of the file of the object data
- uint32_t ar_file_size; // length of the object data
+ lldb::offset_t ar_file_offset; // file offset in bytes from the beginning of the file of the object data
+ lldb::offset_t ar_file_size; // length of the object data
typedef std::vector<Object> collection;
typedef collection::iterator iterator;
@@ -138,7 +140,8 @@ protected:
lldb_private::DataExtractor &data);
Archive (const lldb_private::ArchSpec &arch,
- const lldb_private::TimeValue &mod_time);
+ const lldb_private::TimeValue &mod_time,
+ lldb_private::DataExtractor &data);
~Archive ();
@@ -149,7 +152,7 @@ protected:
}
size_t
- ParseObjects (lldb_private::DataExtractor &data);
+ ParseObjects ();
Object *
FindObject (const lldb_private::ConstString &object_name);
@@ -169,15 +172,22 @@ protected:
bool
HasNoExternalReferences() const;
- protected:
+ lldb_private::DataExtractor &
+ GetData ()
+ {
+ return m_data;
+ }
+ protected:
+ typedef lldb_private::UniqueCStringMap<uint32_t> ObjectNameToIndexMap;
//----------------------------------------------------------------------
// Member Variables
//----------------------------------------------------------------------
lldb_private::ArchSpec m_arch;
lldb_private::TimeValue m_time;
Object::collection m_objects;
- lldb_private::UniqueCStringMap<uint32_t> m_object_name_to_index_map;
+ ObjectNameToIndexMap m_object_name_to_index_map;
+ lldb_private::DataExtractor m_data; ///< The data for this object container so we don't lose data if the .a files gets modified
};
void
Modified: lldb/branches/windows/source/Plugins/ObjectContainer/Universal-Mach-O/ObjectContainerUniversalMachO.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/windows/source/Plugins/ObjectContainer/Universal-Mach-O/ObjectContainerUniversalMachO.cpp?rev=179679&r1=179678&r2=179679&view=diff
==============================================================================
--- lldb/branches/windows/source/Plugins/ObjectContainer/Universal-Mach-O/ObjectContainerUniversalMachO.cpp (original)
+++ lldb/branches/windows/source/Plugins/ObjectContainer/Universal-Mach-O/ObjectContainerUniversalMachO.cpp Wed Apr 17 03:38:48 2013
@@ -8,10 +8,11 @@
//===----------------------------------------------------------------------===//
#include "ObjectContainerUniversalMachO.h"
-#include "lldb/Core/Stream.h"
#include "lldb/Core/ArchSpec.h"
+#include "lldb/Core/DataBuffer.h"
#include "lldb/Core/Module.h"
#include "lldb/Core/PluginManager.h"
+#include "lldb/Core/Stream.h"
#include "lldb/Symbol/ObjectFile.h"
#include "lldb/Target/Target.h"
@@ -52,30 +53,34 @@ ObjectContainerUniversalMachO::CreateIns
(
const lldb::ModuleSP &module_sp,
DataBufferSP& data_sp,
+ lldb::offset_t data_offset,
const FileSpec *file,
- addr_t offset,
- addr_t length
+ lldb::offset_t file_offset,
+ lldb::offset_t length
)
{
- DataExtractor data;
- data.SetData (data_sp, offset, length);
- if (ObjectContainerUniversalMachO::MagicBytesMatch(data))
- {
- std::auto_ptr<ObjectContainerUniversalMachO> container_ap(new ObjectContainerUniversalMachO (module_sp, data_sp, file, offset, length));
- if (container_ap->ParseHeader())
+ // We get data when we aren't trying to look for cached container information,
+ // so only try and look for an architecture slice if we get data
+ if (data_sp)
+ {
+ DataExtractor data;
+ data.SetData (data_sp, data_offset, length);
+ if (ObjectContainerUniversalMachO::MagicBytesMatch(data))
{
- return container_ap.release();
+ std::auto_ptr<ObjectContainerUniversalMachO> container_ap(new ObjectContainerUniversalMachO (module_sp, data_sp, data_offset, file, file_offset, length));
+ if (container_ap->ParseHeader())
+ {
+ return container_ap.release();
+ }
}
}
return NULL;
}
-
-
bool
ObjectContainerUniversalMachO::MagicBytesMatch (const DataExtractor &data)
{
- uint32_t offset = 0;
+ lldb::offset_t offset = 0;
uint32_t magic = data.GetU32(&offset);
return magic == UniversalMagic || magic == UniversalMagicSwapped;
}
@@ -83,12 +88,13 @@ ObjectContainerUniversalMachO::MagicByte
ObjectContainerUniversalMachO::ObjectContainerUniversalMachO
(
const lldb::ModuleSP &module_sp,
- DataBufferSP& dataSP,
+ DataBufferSP& data_sp,
+ lldb::offset_t data_offset,
const FileSpec *file,
- addr_t offset,
- addr_t length
+ lldb::offset_t file_offset,
+ lldb::offset_t length
) :
- ObjectContainer (module_sp, file, offset, length, dataSP),
+ ObjectContainer (module_sp, file, file_offset, length, data_sp, data_offset),
m_header(),
m_fat_archs()
{
@@ -103,9 +109,10 @@ ObjectContainerUniversalMachO::~ObjectCo
bool
ObjectContainerUniversalMachO::ParseHeader ()
{
+ bool success = false;
// Store the file offset for this universal file as we could have a universal .o file
// in a BSD archive, or be contained in another kind of object.
- uint32_t offset = 0;
+ lldb::offset_t offset = 0;
// Universal mach-o files always have their headers in big endian.
m_data.SetByteOrder (eByteOrderBig);
m_header.magic = m_data.GetU32(&offset);
@@ -130,14 +137,17 @@ ObjectContainerUniversalMachO::ParseHead
}
}
}
- return true;
+ success = true;
}
else
{
memset(&m_header, 0, sizeof(m_header));
}
- return false;
+ // We no longer need any data, we parsed all we needed to parse
+ // and cached it in m_header and m_fat_archs
+ m_data.Clear();
+ return success;
}
void
@@ -206,35 +216,31 @@ ObjectContainerUniversalMachO::GetObject
// First, try to find an exact match for the Arch of the Target.
for (arch_idx = 0; arch_idx < m_header.nfat_arch; ++arch_idx)
{
- if (GetArchitectureAtIndex (arch_idx, curr_arch))
- {
- if (arch.IsExactMatch(curr_arch))
- {
- return ObjectFile::FindPlugin (module_sp,
- file,
- m_offset + m_fat_archs[arch_idx].offset,
- m_fat_archs[arch_idx].size,
- m_data.GetSharedDataBuffer());
- }
- }
+ if (GetArchitectureAtIndex (arch_idx, curr_arch) && arch.IsExactMatch(curr_arch))
+ break;
}
// Failing an exact match, try to find a compatible Arch of the Target.
- for (arch_idx = 0; arch_idx < m_header.nfat_arch; ++arch_idx)
+ if (arch_idx >= m_header.nfat_arch)
{
- if (GetArchitectureAtIndex (arch_idx, curr_arch))
+ for (arch_idx = 0; arch_idx < m_header.nfat_arch; ++arch_idx)
{
- if (arch.IsCompatibleMatch(curr_arch))
- {
- return ObjectFile::FindPlugin (module_sp,
- file,
- m_offset + m_fat_archs[arch_idx].offset,
- m_fat_archs[arch_idx].size,
- m_data.GetSharedDataBuffer());
- }
+ if (GetArchitectureAtIndex (arch_idx, curr_arch) && arch.IsCompatibleMatch(curr_arch))
+ break;
}
}
+ if (arch_idx < m_header.nfat_arch)
+ {
+ DataBufferSP data_sp;
+ lldb::offset_t data_offset = 0;
+ return ObjectFile::FindPlugin (module_sp,
+ file,
+ m_offset + m_fat_archs[arch_idx].offset,
+ m_fat_archs[arch_idx].size,
+ data_sp,
+ data_offset);
+ }
}
return ObjectFileSP();
}
Modified: lldb/branches/windows/source/Plugins/ObjectContainer/Universal-Mach-O/ObjectContainerUniversalMachO.h
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/windows/source/Plugins/ObjectContainer/Universal-Mach-O/ObjectContainerUniversalMachO.h?rev=179679&r1=179678&r2=179679&view=diff
==============================================================================
--- lldb/branches/windows/source/Plugins/ObjectContainer/Universal-Mach-O/ObjectContainerUniversalMachO.h (original)
+++ lldb/branches/windows/source/Plugins/ObjectContainer/Universal-Mach-O/ObjectContainerUniversalMachO.h Wed Apr 17 03:38:48 2013
@@ -36,10 +36,11 @@ public:
static lldb_private::ObjectContainer *
CreateInstance (const lldb::ModuleSP &module_sp,
- lldb::DataBufferSP& dataSP,
+ lldb::DataBufferSP& data_sp,
+ lldb::offset_t data_offset,
const lldb_private::FileSpec *file,
- lldb::addr_t offset,
- lldb::addr_t length);
+ lldb::offset_t offset,
+ lldb::offset_t length);
static bool
MagicBytesMatch (const lldb_private::DataExtractor &data);
@@ -48,10 +49,11 @@ public:
// Member Functions
//------------------------------------------------------------------
ObjectContainerUniversalMachO (const lldb::ModuleSP &module_sp,
- lldb::DataBufferSP& dataSP,
+ lldb::DataBufferSP& data_sp,
+ lldb::offset_t data_offset,
const lldb_private::FileSpec *file,
- lldb::addr_t offset,
- lldb::addr_t length);
+ lldb::offset_t offset,
+ lldb::offset_t length);
virtual
~ObjectContainerUniversalMachO();
Modified: lldb/branches/windows/source/Plugins/ObjectFile/ELF/ELFHeader.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/windows/source/Plugins/ObjectFile/ELF/ELFHeader.cpp?rev=179679&r1=179678&r2=179679&view=diff
==============================================================================
--- lldb/branches/windows/source/Plugins/ObjectFile/ELF/ELFHeader.cpp (original)
+++ lldb/branches/windows/source/Plugins/ObjectFile/ELF/ELFHeader.cpp Wed Apr 17 03:38:48 2013
@@ -10,6 +10,8 @@
#include <cstring>
#include "lldb/Core/DataExtractor.h"
+#include "lldb/Core/Section.h"
+#include "lldb/Core/Stream.h"
#include "ELFHeader.h"
@@ -23,20 +25,24 @@ using namespace llvm::ELF;
// GetMaxU64 and GetMaxS64 wrap the similarly named methods from DataExtractor
// with error handling code and provide for parsing a sequence of values.
static bool
-GetMaxU64(const lldb_private::DataExtractor &data,
- uint32_t *offset, uint64_t *value, uint32_t byte_size)
+GetMaxU64(const lldb_private::DataExtractor &data,
+ lldb::offset_t *offset,
+ uint64_t *value,
+ uint32_t byte_size)
{
- const uint32_t saved_offset = *offset;
+ const lldb::offset_t saved_offset = *offset;
*value = data.GetMaxU64(offset, byte_size);
return *offset != saved_offset;
}
static bool
GetMaxU64(const lldb_private::DataExtractor &data,
- uint32_t *offset, uint64_t *value, uint32_t byte_size,
+ lldb::offset_t *offset,
+ uint64_t *value,
+ uint32_t byte_size,
uint32_t count)
{
- uint32_t saved_offset = *offset;
+ lldb::offset_t saved_offset = *offset;
for (uint32_t i = 0; i < count; ++i, ++value)
{
@@ -51,19 +57,23 @@ GetMaxU64(const lldb_private::DataExtrac
static bool
GetMaxS64(const lldb_private::DataExtractor &data,
- uint32_t *offset, int64_t *value, uint32_t byte_size)
+ lldb::offset_t *offset,
+ int64_t *value,
+ uint32_t byte_size)
{
- const uint32_t saved_offset = *offset;
+ const lldb::offset_t saved_offset = *offset;
*value = data.GetMaxS64(offset, byte_size);
return *offset != saved_offset;
}
static bool
GetMaxS64(const lldb_private::DataExtractor &data,
- uint32_t *offset, int64_t *value, uint32_t byte_size,
+ lldb::offset_t *offset,
+ int64_t *value,
+ uint32_t byte_size,
uint32_t count)
{
- uint32_t saved_offset = *offset;
+ lldb::offset_t saved_offset = *offset;
for (uint32_t i = 0; i < count; ++i, ++value)
{
@@ -95,7 +105,7 @@ ELFHeader::GetByteOrder() const
}
bool
-ELFHeader::Parse(lldb_private::DataExtractor &data, uint32_t *offset)
+ELFHeader::Parse(lldb_private::DataExtractor &data, lldb::offset_t *offset)
{
// Read e_ident. This provides byte order and address size info.
if (data.GetU8(offset, &e_ident, EI_NIDENT) == NULL)
@@ -190,7 +200,7 @@ ELFSectionHeader::ELFSectionHeader()
bool
ELFSectionHeader::Parse(const lldb_private::DataExtractor &data,
- uint32_t *offset)
+ lldb::offset_t *offset)
{
const unsigned byte_size = data.GetAddressByteSize();
@@ -225,8 +235,92 @@ ELFSymbol::ELFSymbol()
memset(this, 0, sizeof(ELFSymbol));
}
+#define ENUM_TO_CSTR(e) case e: return #e
+
+const char *
+ELFSymbol::bindingToCString(unsigned char binding)
+{
+ switch (binding)
+ {
+ ENUM_TO_CSTR(STB_LOCAL);
+ ENUM_TO_CSTR(STB_GLOBAL);
+ ENUM_TO_CSTR(STB_WEAK);
+ ENUM_TO_CSTR(STB_LOOS);
+ ENUM_TO_CSTR(STB_HIOS);
+ ENUM_TO_CSTR(STB_LOPROC);
+ ENUM_TO_CSTR(STB_HIPROC);
+ }
+ return "";
+}
+
+const char *
+ELFSymbol::typeToCString(unsigned char type)
+{
+ switch (type)
+ {
+ ENUM_TO_CSTR(STT_NOTYPE);
+ ENUM_TO_CSTR(STT_OBJECT);
+ ENUM_TO_CSTR(STT_FUNC);
+ ENUM_TO_CSTR(STT_SECTION);
+ ENUM_TO_CSTR(STT_FILE);
+ ENUM_TO_CSTR(STT_COMMON);
+ ENUM_TO_CSTR(STT_TLS);
+ ENUM_TO_CSTR(STT_LOOS);
+ ENUM_TO_CSTR(STT_HIOS);
+ ENUM_TO_CSTR(STT_GNU_IFUNC);
+ ENUM_TO_CSTR(STT_LOPROC);
+ ENUM_TO_CSTR(STT_HIPROC);
+ }
+ return "";
+}
+
+const char *
+ELFSymbol::sectionIndexToCString (elf_half shndx,
+ const lldb_private::SectionList *section_list)
+{
+ switch (shndx)
+ {
+ ENUM_TO_CSTR(SHN_UNDEF);
+ ENUM_TO_CSTR(SHN_LOPROC);
+ ENUM_TO_CSTR(SHN_HIPROC);
+ ENUM_TO_CSTR(SHN_LOOS);
+ ENUM_TO_CSTR(SHN_HIOS);
+ ENUM_TO_CSTR(SHN_ABS);
+ ENUM_TO_CSTR(SHN_COMMON);
+ ENUM_TO_CSTR(SHN_XINDEX);
+ default:
+ {
+ const lldb_private::Section *section = section_list->GetSectionAtIndex(shndx).get();
+ if (section)
+ return section->GetName().AsCString("");
+ }
+ break;
+ }
+ return "";
+}
+
+void
+ELFSymbol::Dump (lldb_private::Stream *s,
+ uint32_t idx,
+ const lldb_private::DataExtractor *strtab_data,
+ const lldb_private::SectionList *section_list)
+{
+ s->Printf("[%3u] 0x%16.16llx 0x%16.16llx 0x%8.8x 0x%2.2x (%-10s %-13s) 0x%2.2x 0x%4.4x (%-10s) %s\n",
+ idx,
+ st_value,
+ st_size,
+ st_name,
+ st_info,
+ bindingToCString (getBinding()),
+ typeToCString (getType()),
+ st_other,
+ st_shndx,
+ sectionIndexToCString (st_shndx, section_list),
+ strtab_data ? strtab_data->PeekCStr(st_name) : "");
+}
+
bool
-ELFSymbol::Parse(const lldb_private::DataExtractor &data, uint32_t *offset)
+ELFSymbol::Parse(const lldb_private::DataExtractor &data, lldb::offset_t *offset)
{
const unsigned byte_size = data.GetAddressByteSize();
const bool parsing_32 = byte_size == 4;
@@ -276,7 +370,7 @@ ELFProgramHeader::ELFProgramHeader()
bool
ELFProgramHeader::Parse(const lldb_private::DataExtractor &data,
- uint32_t *offset)
+ lldb::offset_t *offset)
{
const uint32_t byte_size = data.GetAddressByteSize();
const bool parsing_32 = byte_size == 4;
@@ -320,7 +414,7 @@ ELFDynamic::ELFDynamic()
}
bool
-ELFDynamic::Parse(const lldb_private::DataExtractor &data, uint32_t *offset)
+ELFDynamic::Parse(const lldb_private::DataExtractor &data, lldb::offset_t *offset)
{
const unsigned byte_size = data.GetAddressByteSize();
return GetMaxS64(data, offset, &d_tag, byte_size, 2);
@@ -335,7 +429,7 @@ ELFRel::ELFRel()
}
bool
-ELFRel::Parse(const lldb_private::DataExtractor &data, uint32_t *offset)
+ELFRel::Parse(const lldb_private::DataExtractor &data, lldb::offset_t *offset)
{
const unsigned byte_size = data.GetAddressByteSize();
@@ -355,7 +449,7 @@ ELFRela::ELFRela()
}
bool
-ELFRela::Parse(const lldb_private::DataExtractor &data, uint32_t *offset)
+ELFRela::Parse(const lldb_private::DataExtractor &data, lldb::offset_t *offset)
{
const unsigned byte_size = data.GetAddressByteSize();
Modified: lldb/branches/windows/source/Plugins/ObjectFile/ELF/ELFHeader.h
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/windows/source/Plugins/ObjectFile/ELF/ELFHeader.h?rev=179679&r1=179678&r2=179679&view=diff
==============================================================================
--- lldb/branches/windows/source/Plugins/ObjectFile/ELF/ELFHeader.h (original)
+++ lldb/branches/windows/source/Plugins/ObjectFile/ELF/ELFHeader.h Wed Apr 17 03:38:48 2013
@@ -123,7 +123,7 @@ struct ELFHeader
/// True if the ELFSectionHeader was successfully read and false
/// otherwise.
bool
- Parse(lldb_private::DataExtractor &data, uint32_t *offset);
+ Parse(lldb_private::DataExtractor &data, lldb::offset_t *offset);
//--------------------------------------------------------------------------
/// Examines at most EI_NIDENT bytes starting from the given pointer and
@@ -181,7 +181,7 @@ struct ELFSectionHeader
/// True if the ELFSectionHeader was successfully read and false
/// otherwise.
bool
- Parse(const lldb_private::DataExtractor &data, uint32_t *offset);
+ Parse(const lldb_private::DataExtractor &data, lldb::offset_t *offset);
};
//------------------------------------------------------------------------------
@@ -216,7 +216,7 @@ struct ELFProgramHeader
/// True if the ELFProgramHeader was successfully read and false
/// otherwise.
bool
- Parse(const lldb_private::DataExtractor &data, uint32_t *offset);
+ Parse(const lldb_private::DataExtractor &data, lldb::offset_t *offset);
};
//------------------------------------------------------------------------------
@@ -244,6 +244,16 @@ struct ELFSymbol
st_info = (binding << 4) + (type & 0x0F);
}
+ static const char *
+ bindingToCString(unsigned char binding);
+
+ static const char *
+ typeToCString(unsigned char type);
+
+ static const char *
+ sectionIndexToCString(elf_half shndx,
+ const lldb_private::SectionList *section_list);
+
/// Parse an ELFSymbol entry from the given DataExtractor starting at
/// position \p offset. The address size of the DataExtractor determines if
/// a 32 or 64 bit object is to be parsed.
@@ -259,7 +269,13 @@ struct ELFSymbol
/// @return
/// True if the ELFSymbol was successfully read and false otherwise.
bool
- Parse(const lldb_private::DataExtractor &data, uint32_t *offset);
+ Parse(const lldb_private::DataExtractor &data, lldb::offset_t *offset);
+
+ void
+ Dump (lldb_private::Stream *s,
+ uint32_t idx,
+ const lldb_private::DataExtractor *strtab_data,
+ const lldb_private::SectionList *section_list);
};
//------------------------------------------------------------------------------
@@ -292,7 +308,7 @@ struct ELFDynamic
/// True if the ELFDynamic entry was successfully read and false
/// otherwise.
bool
- Parse(const lldb_private::DataExtractor &data, uint32_t *offset);
+ Parse(const lldb_private::DataExtractor &data, lldb::offset_t *offset);
};
//------------------------------------------------------------------------------
@@ -320,7 +336,7 @@ struct ELFRel
/// @return
/// True if the ELFRel entry was successfully read and false otherwise.
bool
- Parse(const lldb_private::DataExtractor &data, uint32_t *offset);
+ Parse(const lldb_private::DataExtractor &data, lldb::offset_t *offset);
/// Returns the type when the given entry represents a 32-bit relocation.
static unsigned
@@ -379,7 +395,7 @@ struct ELFRela
/// @return
/// True if the ELFRela entry was successfully read and false otherwise.
bool
- Parse(const lldb_private::DataExtractor &data, uint32_t *offset);
+ Parse(const lldb_private::DataExtractor &data, lldb::offset_t *offset);
/// Returns the type when the given entry represents a 32-bit relocation.
static unsigned
Modified: lldb/branches/windows/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/windows/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp?rev=179679&r1=179678&r2=179679&view=diff
==============================================================================
--- lldb/branches/windows/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp (original)
+++ lldb/branches/windows/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp Wed Apr 17 03:38:48 2013
@@ -53,7 +53,7 @@ public:
~ELFRelocation();
bool
- Parse(const lldb_private::DataExtractor &data, uint32_t *offset);
+ Parse(const lldb_private::DataExtractor &data, lldb::offset_t *offset);
static unsigned
RelocType32(const ELFRelocation &rel);
@@ -94,7 +94,7 @@ ELFRelocation::~ELFRelocation()
}
bool
-ELFRelocation::Parse(const lldb_private::DataExtractor &data, uint32_t *offset)
+ELFRelocation::Parse(const lldb_private::DataExtractor &data, lldb::offset_t *offset)
{
if (reloc.is<ELFRel*>())
return reloc.get<ELFRel*>()->Parse(data, offset);
@@ -173,19 +173,32 @@ ObjectFileELF::GetPluginDescriptionStati
ObjectFile *
ObjectFileELF::CreateInstance (const lldb::ModuleSP &module_sp,
DataBufferSP &data_sp,
- const FileSpec *file,
- addr_t offset,
- addr_t length)
+ lldb::offset_t data_offset,
+ const lldb_private::FileSpec* file,
+ lldb::offset_t file_offset,
+ lldb::offset_t length)
{
- if (data_sp && data_sp->GetByteSize() > (llvm::ELF::EI_NIDENT + offset))
+ if (!data_sp)
{
- const uint8_t *magic = data_sp->GetBytes() + offset;
+ data_sp = file->MemoryMapFileContents(file_offset, length);
+ data_offset = 0;
+ }
+
+ if (data_sp && data_sp->GetByteSize() > (llvm::ELF::EI_NIDENT + data_offset))
+ {
+ const uint8_t *magic = data_sp->GetBytes() + data_offset;
if (ELFHeader::MagicBytesMatch(magic))
{
+ // Update the data to contain the entire file if it doesn't already
+ if (data_sp->GetByteSize() < length) {
+ data_sp = file->MemoryMapFileContents(file_offset, length);
+ data_offset = 0;
+ magic = data_sp->GetBytes();
+ }
unsigned address_size = ELFHeader::AddressSizeInBytes(magic);
if (address_size == 4 || address_size == 8)
{
- std::auto_ptr<ObjectFileELF> objfile_ap(new ObjectFileELF(module_sp, data_sp, file, offset, length));
+ std::auto_ptr<ObjectFileELF> objfile_ap(new ObjectFileELF(module_sp, data_sp, data_offset, file, file_offset, length));
ArchSpec spec;
if (objfile_ap->GetArchitecture(spec) &&
objfile_ap->SetModulesArchitecture(spec))
@@ -232,16 +245,15 @@ ObjectFileELF::GetPluginVersion()
//------------------------------------------------------------------
ObjectFileELF::ObjectFileELF (const lldb::ModuleSP &module_sp,
- DataBufferSP& dataSP,
+ DataBufferSP& data_sp,
+ lldb::offset_t data_offset,
const FileSpec* file,
- addr_t offset,
- addr_t length) :
- ObjectFile(module_sp, file, offset, length, dataSP),
+ lldb::offset_t file_offset,
+ lldb::offset_t length) :
+ ObjectFile(module_sp, file, file_offset, length, data_sp, data_offset),
m_header(),
m_program_headers(),
m_section_headers(),
- m_sections_ap(),
- m_symtab_ap(),
m_filespec_ap(),
m_shstr_data()
{
@@ -270,28 +282,28 @@ ObjectFileELF::GetByteOrder() const
return eByteOrderInvalid;
}
-size_t
+uint32_t
ObjectFileELF::GetAddressByteSize() const
{
return m_data.GetAddressByteSize();
}
-unsigned
+size_t
ObjectFileELF::SectionIndex(const SectionHeaderCollIter &I)
{
- return std::distance(m_section_headers.begin(), I) + 1;
+ return std::distance(m_section_headers.begin(), I) + 1u;
}
-unsigned
+size_t
ObjectFileELF::SectionIndex(const SectionHeaderCollConstIter &I) const
{
- return std::distance(m_section_headers.begin(), I) + 1;
+ return std::distance(m_section_headers.begin(), I) + 1u;
}
bool
ObjectFileELF::ParseHeader()
{
- uint32_t offset = GetOffset();
+ lldb::offset_t offset = GetFileOffset();
return m_header.Parse(m_data, &offset);
}
@@ -445,8 +457,8 @@ ObjectFileELF::ParseDependentModules()
ReadSectionData(dynstr, dynstr_data))
{
ELFDynamic symbol;
- const unsigned section_size = dynsym_data.GetByteSize();
- unsigned offset = 0;
+ const lldb::offset_t section_size = dynsym_data.GetByteSize();
+ lldb::offset_t offset = 0;
// The only type of entries we are concerned with are tagged DT_NEEDED,
// yielding the name of a required library.
@@ -492,7 +504,7 @@ ObjectFileELF::ParseProgramHeaders()
return 0;
uint32_t idx;
- uint32_t offset;
+ lldb::offset_t offset;
for (idx = 0, offset = 0; idx < m_header.e_phnum; ++idx)
{
if (m_program_headers[idx].Parse(data, &offset) == false)
@@ -530,7 +542,7 @@ ObjectFileELF::ParseSectionHeaders()
return 0;
uint32_t idx;
- uint32_t offset;
+ lldb::offset_t offset;
for (idx = 0, offset = 0; idx < m_header.e_shnum; ++idx)
{
if (m_section_headers[idx].Parse(data, &offset) == false)
@@ -698,9 +710,8 @@ ParseSymbols(Symtab *symtab,
const DataExtractor &strtab_data)
{
ELFSymbol symbol;
- uint32_t offset = 0;
- const unsigned num_symbols =
- symtab_data.GetByteSize() / symtab_shdr->sh_entsize;
+ lldb::offset_t offset = 0;
+ const size_t num_symbols = symtab_data.GetByteSize() / symtab_shdr->sh_entsize;
static ConstString text_section_name(".text");
static ConstString init_section_name(".init");
@@ -714,11 +725,20 @@ ParseSymbols(Symtab *symtab,
static ConstString data2_section_name(".data1");
static ConstString bss_section_name(".bss");
+ //StreamFile strm(stdout, false);
unsigned i;
for (i = 0; i < num_symbols; ++i)
{
if (symbol.Parse(symtab_data, &offset) == false)
break;
+
+ const char *symbol_name = strtab_data.PeekCStr(symbol.st_name);
+
+ // No need to add symbols that have no names
+ if (symbol_name == NULL || symbol_name[0] == '\0')
+ continue;
+
+ //symbol.Dump (&strm, i, &strtab_data, section_list);
SectionSP symbol_section_sp;
SymbolType symbol_type = eSymbolTypeInvalid;
@@ -737,37 +757,47 @@ ParseSymbols(Symtab *symtab,
break;
}
- switch (symbol.getType())
+ // If a symbol is undefined do not process it further even if it has a STT type
+ if (symbol_type != eSymbolTypeUndefined)
{
- default:
- case STT_NOTYPE:
- // The symbol's type is not specified.
- break;
+ switch (symbol.getType())
+ {
+ default:
+ case STT_NOTYPE:
+ // The symbol's type is not specified.
+ break;
- case STT_OBJECT:
- // The symbol is associated with a data object, such as a variable,
- // an array, etc.
- symbol_type = eSymbolTypeData;
- break;
+ case STT_OBJECT:
+ // The symbol is associated with a data object, such as a variable,
+ // an array, etc.
+ symbol_type = eSymbolTypeData;
+ break;
- case STT_FUNC:
- // The symbol is associated with a function or other executable code.
- symbol_type = eSymbolTypeCode;
- break;
+ case STT_FUNC:
+ // The symbol is associated with a function or other executable code.
+ symbol_type = eSymbolTypeCode;
+ break;
- case STT_SECTION:
- // The symbol is associated with a section. Symbol table entries of
- // this type exist primarily for relocation and normally have
- // STB_LOCAL binding.
- break;
+ case STT_SECTION:
+ // The symbol is associated with a section. Symbol table entries of
+ // this type exist primarily for relocation and normally have
+ // STB_LOCAL binding.
+ break;
- case STT_FILE:
- // Conventionally, the symbol's name gives the name of the source
- // file associated with the object file. A file symbol has STB_LOCAL
- // binding, its section index is SHN_ABS, and it precedes the other
- // STB_LOCAL symbols for the file, if it is present.
- symbol_type = eSymbolTypeObjectFile;
- break;
+ case STT_FILE:
+ // Conventionally, the symbol's name gives the name of the source
+ // file associated with the object file. A file symbol has STB_LOCAL
+ // binding, its section index is SHN_ABS, and it precedes the other
+ // STB_LOCAL symbols for the file, if it is present.
+ symbol_type = eSymbolTypeSourceFile;
+ break;
+
+ case STT_GNU_IFUNC:
+ // The symbol is associated with an indirect function. The actual
+ // function will be resolved if it is referenced.
+ symbol_type = eSymbolTypeResolver;
+ break;
+ }
}
if (symbol_type == eSymbolTypeInvalid)
@@ -797,7 +827,6 @@ ParseSymbols(Symtab *symtab,
uint64_t symbol_value = symbol.st_value;
if (symbol_section_sp)
symbol_value -= symbol_section_sp->GetFileAddress();
- const char *symbol_name = strtab_data.PeekCStr(symbol.st_name);
bool is_global = symbol.getBinding() == STB_GLOBAL;
uint32_t flags = symbol.st_other << 8 | symbol.st_info;
bool is_mangled = symbol_name ? (symbol_name[0] == '_' && symbol_name[1] == 'Z') : false;
@@ -813,6 +842,7 @@ ParseSymbols(Symtab *symtab,
symbol_section_sp, // Section in which this symbol is defined or null.
symbol_value, // Offset in section or symbol value.
symbol.st_size, // Size in bytes of this symbol.
+ true, // Size is valid
flags); // Symbol flags.
symtab->AddSymbol(dc_symbol);
}
@@ -877,8 +907,8 @@ ObjectFileELF::ParseDynamicSymbols()
DataExtractor dynsym_data;
if (ReadSectionData(dynsym, dynsym_data))
{
- const unsigned section_size = dynsym_data.GetByteSize();
- unsigned cursor = 0;
+ const lldb::offset_t section_size = dynsym_data.GetByteSize();
+ lldb::offset_t cursor = 0;
while (cursor < section_size)
{
@@ -956,9 +986,9 @@ ParsePLTRelocations(Symtab *symbol_table
{
ELFRelocation rel(rel_type);
ELFSymbol symbol;
- uint32_t offset = 0;
- const unsigned plt_entsize = plt_hdr->sh_entsize;
- const unsigned num_relocations = rel_hdr->sh_size / rel_hdr->sh_entsize;
+ lldb::offset_t offset = 0;
+ const elf_xword plt_entsize = plt_hdr->sh_entsize;
+ const elf_xword num_relocations = rel_hdr->sh_size / rel_hdr->sh_entsize;
typedef unsigned (*reloc_info_fn)(const ELFRelocation &rel);
reloc_info_fn reloc_type;
@@ -985,7 +1015,7 @@ ParsePLTRelocations(Symtab *symbol_table
if (reloc_type(rel) != slot_type)
continue;
- unsigned symbol_offset = reloc_symbol(rel) * sym_hdr->sh_entsize;
+ lldb::offset_t symbol_offset = reloc_symbol(rel) * sym_hdr->sh_entsize;
uint64_t plt_index = (i + 1) * plt_entsize;
if (!symbol.Parse(symtab_data, &symbol_offset))
@@ -1006,6 +1036,7 @@ ParsePLTRelocations(Symtab *symbol_table
plt_section_sp, // Section in which this symbol is defined or null.
plt_index, // Offset in section or symbol value.
plt_entsize, // Size in bytes of this symbol.
+ true, // Size is valid
0); // Symbol flags.
symbol_table->AddSymbol(jump_symbol);
@@ -1378,7 +1409,7 @@ ObjectFileELF::DumpELFSectionHeader_sh_t
// Dump an token value for the ELF section header member sh_flags
//----------------------------------------------------------------------
void
-ObjectFileELF::DumpELFSectionHeader_sh_flags(Stream *s, elf_word sh_flags)
+ObjectFileELF::DumpELFSectionHeader_sh_flags(Stream *s, elf_xword sh_flags)
{
*s << ((sh_flags & SHF_WRITE) ? "WRITE" : " ")
<< (((sh_flags & SHF_WRITE) && (sh_flags & SHF_ALLOC)) ? '+' : ' ')
Modified: lldb/branches/windows/source/Plugins/ObjectFile/ELF/ObjectFileELF.h
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/windows/source/Plugins/ObjectFile/ELF/ObjectFileELF.h?rev=179679&r1=179678&r2=179679&view=diff
==============================================================================
--- lldb/branches/windows/source/Plugins/ObjectFile/ELF/ObjectFileELF.h (original)
+++ lldb/branches/windows/source/Plugins/ObjectFile/ELF/ObjectFileELF.h Wed Apr 17 03:38:48 2013
@@ -46,10 +46,11 @@ public:
static lldb_private::ObjectFile *
CreateInstance(const lldb::ModuleSP &module_sp,
- lldb::DataBufferSP& dataSP,
+ lldb::DataBufferSP& data_sp,
+ lldb::offset_t data_offset,
const lldb_private::FileSpec* file,
- lldb::addr_t offset,
- lldb::addr_t length);
+ lldb::offset_t file_offset,
+ lldb::offset_t length);
static lldb_private::ObjectFile *
CreateMemoryInstance (const lldb::ModuleSP &module_sp,
@@ -84,7 +85,7 @@ public:
virtual bool
IsExecutable () const;
- virtual size_t
+ virtual uint32_t
GetAddressByteSize() const;
virtual lldb_private::Symtab *
@@ -119,10 +120,11 @@ public:
private:
ObjectFileELF(const lldb::ModuleSP &module_sp,
- lldb::DataBufferSP& dataSP,
+ lldb::DataBufferSP& data_sp,
+ lldb::offset_t data_offset,
const lldb_private::FileSpec* file,
- lldb::addr_t offset,
- lldb::addr_t length);
+ lldb::offset_t offset,
+ lldb::offset_t length);
typedef std::vector<elf::ELFProgramHeader> ProgramHeaderColl;
typedef ProgramHeaderColl::iterator ProgramHeaderCollIter;
@@ -151,12 +153,6 @@ private:
/// Collection of symbols from the dynamic table.
DynamicSymbolColl m_dynamic_symbols;
- /// List of sections present in this ELF object file.
- mutable std::auto_ptr<lldb_private::SectionList> m_sections_ap;
-
- /// Table of all non-dynamic symbols present in this object file.
- mutable std::auto_ptr<lldb_private::Symtab> m_symtab_ap;
-
/// List of file specifications corresponding to the modules (shared
/// libraries) on which this object file depends.
mutable std::auto_ptr<lldb_private::FileSpecList> m_filespec_ap;
@@ -168,11 +164,11 @@ private:
lldb_private::Address m_entry_point_address;
/// Returns a 1 based index of the given section header.
- unsigned
+ size_t
SectionIndex(const SectionHeaderCollIter &I);
/// Returns a 1 based index of the given section header.
- unsigned
+ size_t
SectionIndex(const SectionHeaderCollConstIter &I) const;
/// Parses all section headers present in this object file and populates
@@ -282,7 +278,7 @@ private:
static void
DumpELFSectionHeader_sh_flags(lldb_private::Stream *s,
- elf::elf_word sh_flags);
+ elf::elf_xword sh_flags);
//@}
/// ELF dependent module dump routine.
Modified: lldb/branches/windows/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/windows/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp?rev=179679&r1=179678&r2=179679&view=diff
==============================================================================
--- lldb/branches/windows/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp (original)
+++ lldb/branches/windows/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp Wed Apr 17 03:38:48 2013
@@ -15,6 +15,7 @@
#include "lldb/lldb-private-log.h"
#include "lldb/Core/ArchSpec.h"
#include "lldb/Core/DataBuffer.h"
+#include "lldb/Core/Debugger.h"
#include "lldb/Core/FileSpecList.h"
#include "lldb/Core/Log.h"
#include "lldb/Core/Module.h"
@@ -28,6 +29,7 @@
#include "lldb/Host/Host.h"
#include "lldb/Host/FileSpec.h"
#include "lldb/Symbol/ClangNamespaceDecl.h"
+#include "lldb/Symbol/DWARFCallFrameInfo.h"
#include "lldb/Symbol/ObjectFile.h"
#include "lldb/Target/Platform.h"
#include "lldb/Target/Process.h"
@@ -36,12 +38,20 @@
#include "Plugins/Process/Utility/RegisterContextDarwin_i386.h"
#include "Plugins/Process/Utility/RegisterContextDarwin_x86_64.h"
+#if defined (__APPLE__) && defined (__arm__)
+// GetLLDBSharedCacheUUID() needs to call dlsym()
+#include <dlfcn.h>
+#endif
using namespace lldb;
using namespace lldb_private;
using namespace llvm::MachO;
-class RegisterContextDarwin_x86_64_Mach : public RegisterContextDarwin_x86_64
+#ifdef _WIN32
+typedef char uuid_t[16];
+#endif
+
+class RegisterContextDarwin_x86_64_Mach : public RegisterContextDarwin_x86_64
{
public:
RegisterContextDarwin_x86_64_Mach (lldb_private::Thread &thread, const DataExtractor &data) :
@@ -59,12 +69,12 @@ public:
void
SetRegisterDataFrom_LC_THREAD (const DataExtractor &data)
{
- uint32_t offset = 0;
+ lldb::offset_t offset = 0;
SetError (GPRRegSet, Read, -1);
SetError (FPURegSet, Read, -1);
SetError (EXCRegSet, Read, -1);
bool done = false;
-
+
while (!done)
{
int flavor = data.GetU32 (&offset);
@@ -81,13 +91,13 @@ public:
(&gpr.rax)[i] = data.GetU64(&offset);
SetError (GPRRegSet, Read, 0);
done = true;
-
+
break;
case FPURegSet:
// TODO: fill in FPU regs....
//SetError (FPURegSet, Read, -1);
done = true;
-
+
break;
case EXCRegSet:
exc.trapno = data.GetU32(&offset);
@@ -102,7 +112,7 @@ public:
// fancy flavors that encapsulate of the the above
// falvors...
break;
-
+
default:
done = true;
break;
@@ -116,31 +126,31 @@ protected:
{
return 0;
}
-
+
virtual int
DoReadFPU (lldb::tid_t tid, int flavor, FPU &fpu)
{
return 0;
}
-
+
virtual int
DoReadEXC (lldb::tid_t tid, int flavor, EXC &exc)
{
return 0;
}
-
+
virtual int
DoWriteGPR (lldb::tid_t tid, int flavor, const GPR &gpr)
{
return 0;
}
-
+
virtual int
DoWriteFPU (lldb::tid_t tid, int flavor, const FPU &fpu)
{
return 0;
}
-
+
virtual int
DoWriteEXC (lldb::tid_t tid, int flavor, const EXC &exc)
{
@@ -149,7 +159,7 @@ protected:
};
-class RegisterContextDarwin_i386_Mach : public RegisterContextDarwin_i386
+class RegisterContextDarwin_i386_Mach : public RegisterContextDarwin_i386
{
public:
RegisterContextDarwin_i386_Mach (lldb_private::Thread &thread, const DataExtractor &data) :
@@ -157,22 +167,22 @@ public:
{
SetRegisterDataFrom_LC_THREAD (data);
}
-
+
virtual void
InvalidateAllRegisters ()
{
// Do nothing... registers are always valid...
}
-
+
void
SetRegisterDataFrom_LC_THREAD (const DataExtractor &data)
{
- uint32_t offset = 0;
+ lldb::offset_t offset = 0;
SetError (GPRRegSet, Read, -1);
SetError (FPURegSet, Read, -1);
SetError (EXCRegSet, Read, -1);
bool done = false;
-
+
while (!done)
{
int flavor = data.GetU32 (&offset);
@@ -210,7 +220,7 @@ public:
// fancy flavors that encapsulate of the the above
// falvors...
break;
-
+
default:
done = true;
break;
@@ -224,31 +234,31 @@ protected:
{
return 0;
}
-
+
virtual int
DoReadFPU (lldb::tid_t tid, int flavor, FPU &fpu)
{
return 0;
}
-
+
virtual int
DoReadEXC (lldb::tid_t tid, int flavor, EXC &exc)
{
return 0;
}
-
+
virtual int
DoWriteGPR (lldb::tid_t tid, int flavor, const GPR &gpr)
{
return 0;
}
-
+
virtual int
DoWriteFPU (lldb::tid_t tid, int flavor, const FPU &fpu)
{
return 0;
}
-
+
virtual int
DoWriteEXC (lldb::tid_t tid, int flavor, const EXC &exc)
{
@@ -256,7 +266,7 @@ protected:
}
};
-class RegisterContextDarwin_arm_Mach : public RegisterContextDarwin_arm
+class RegisterContextDarwin_arm_Mach : public RegisterContextDarwin_arm
{
public:
RegisterContextDarwin_arm_Mach (lldb_private::Thread &thread, const DataExtractor &data) :
@@ -264,17 +274,17 @@ public:
{
SetRegisterDataFrom_LC_THREAD (data);
}
-
+
virtual void
InvalidateAllRegisters ()
{
// Do nothing... registers are always valid...
}
-
+
void
SetRegisterDataFrom_LC_THREAD (const DataExtractor &data)
{
- uint32_t offset = 0;
+ lldb::offset_t offset = 0;
SetError (GPRRegSet, Read, -1);
SetError (FPURegSet, Read, -1);
SetError (EXCRegSet, Read, -1);
@@ -305,13 +315,13 @@ protected:
{
return 0;
}
-
+
virtual int
DoReadFPU (lldb::tid_t tid, int flavor, FPU &fpu)
{
return 0;
}
-
+
virtual int
DoReadEXC (lldb::tid_t tid, int flavor, EXC &exc)
{
@@ -323,25 +333,25 @@ protected:
{
return -1;
}
-
+
virtual int
DoWriteGPR (lldb::tid_t tid, int flavor, const GPR &gpr)
{
return 0;
}
-
+
virtual int
DoWriteFPU (lldb::tid_t tid, int flavor, const FPU &fpu)
{
return 0;
}
-
+
virtual int
DoWriteEXC (lldb::tid_t tid, int flavor, const EXC &exc)
{
return 0;
}
-
+
virtual int
DoWriteDBG (lldb::tid_t tid, int flavor, const DBG &dbg)
{
@@ -379,13 +389,29 @@ ObjectFileMachO::GetPluginDescriptionSta
return "Mach-o object file reader (32 and 64 bit)";
}
-
ObjectFile *
-ObjectFileMachO::CreateInstance (const lldb::ModuleSP &module_sp, DataBufferSP& data_sp, const FileSpec* file, addr_t offset, addr_t length)
+ObjectFileMachO::CreateInstance (const lldb::ModuleSP &module_sp,
+ DataBufferSP& data_sp,
+ lldb::offset_t data_offset,
+ const FileSpec* file,
+ lldb::offset_t file_offset,
+ lldb::offset_t length)
{
- if (ObjectFileMachO::MagicBytesMatch(data_sp, offset, length))
+ if (!data_sp)
+ {
+ data_sp = file->MemoryMapFileContents(file_offset, length);
+ data_offset = 0;
+ }
+
+ if (ObjectFileMachO::MagicBytesMatch(data_sp, data_offset, length))
{
- std::auto_ptr<ObjectFile> objfile_ap(new ObjectFileMachO (module_sp, data_sp, file, offset, length));
+ // Update the data to contain the entire file if it doesn't already
+ if (data_sp->GetByteSize() < length)
+ {
+ data_sp = file->MemoryMapFileContents(file_offset, length);
+ data_offset = 0;
+ }
+ std::auto_ptr<ObjectFile> objfile_ap(new ObjectFileMachO (module_sp, data_sp, data_offset, file, file_offset, length));
if (objfile_ap.get() && objfile_ap->ParseHeader())
return objfile_ap.release();
}
@@ -393,9 +419,9 @@ ObjectFileMachO::CreateInstance (const l
}
ObjectFile *
-ObjectFileMachO::CreateMemoryInstance (const lldb::ModuleSP &module_sp,
- DataBufferSP& data_sp,
- const ProcessSP &process_sp,
+ObjectFileMachO::CreateMemoryInstance (const lldb::ModuleSP &module_sp,
+ DataBufferSP& data_sp,
+ const ProcessSP &process_sp,
lldb::addr_t header_addr)
{
if (ObjectFileMachO::MagicBytesMatch(data_sp, 0, data_sp->GetByteSize()))
@@ -404,7 +430,7 @@ ObjectFileMachO::CreateMemoryInstance (c
if (objfile_ap.get() && objfile_ap->ParseHeader())
return objfile_ap.release();
}
- return NULL;
+ return NULL;
}
@@ -467,22 +493,25 @@ MachHeaderSizeFromMagic(uint32_t magic)
bool
-ObjectFileMachO::MagicBytesMatch (DataBufferSP& data_sp,
- lldb::addr_t data_offset,
+ObjectFileMachO::MagicBytesMatch (DataBufferSP& data_sp,
+ lldb::addr_t data_offset,
lldb::addr_t data_length)
{
DataExtractor data;
data.SetData (data_sp, data_offset, data_length);
- uint32_t offset = 0;
+ lldb::offset_t offset = 0;
uint32_t magic = data.GetU32(&offset);
return MachHeaderSizeFromMagic(magic) != 0;
}
-ObjectFileMachO::ObjectFileMachO(const lldb::ModuleSP &module_sp, DataBufferSP& data_sp, const FileSpec* file, addr_t offset, addr_t length) :
- ObjectFile(module_sp, file, offset, length, data_sp),
- m_sections_ap(),
- m_symtab_ap(),
+ObjectFileMachO::ObjectFileMachO(const lldb::ModuleSP &module_sp,
+ DataBufferSP& data_sp,
+ lldb::offset_t data_offset,
+ const FileSpec* file,
+ lldb::offset_t file_offset,
+ lldb::offset_t length) :
+ ObjectFile(module_sp, file, file_offset, length, data_sp, data_offset),
m_mach_segments(),
m_mach_sections(),
m_entry_point_address(),
@@ -498,8 +527,6 @@ ObjectFileMachO::ObjectFileMachO (const
const lldb::ProcessSP &process_sp,
lldb::addr_t header_addr) :
ObjectFile(module_sp, process_sp, header_addr, header_data_sp),
- m_sections_ap(),
- m_symtab_ap(),
m_mach_segments(),
m_mach_sections(),
m_entry_point_address(),
@@ -523,7 +550,7 @@ ObjectFileMachO::ParseHeader ()
{
lldb_private::Mutex::Locker locker(module_sp->GetMutex());
bool can_parse = false;
- uint32_t offset = 0;
+ lldb::offset_t offset = 0;
m_data.SetByteOrder (lldb::endian::InlHostByteOrder());
// Leave magic in the original byte order
m_header.magic = m_data.GetU32(&offset);
@@ -562,7 +589,7 @@ ObjectFileMachO::ParseHeader ()
m_data.GetU32(&offset, &m_header.cputype, 6);
ArchSpec mach_arch(eArchTypeMachO, m_header.cputype, m_header.cpusubtype);
-
+
// Check if the module has a required architecture
const ArchSpec &module_arch = module_sp->GetArchitecture();
if (module_arch.IsValid() && !module_arch.IsCompatibleMatch(mach_arch))
@@ -577,12 +604,12 @@ ObjectFileMachO::ParseHeader ()
ProcessSP process_sp (m_process_wp.lock());
if (process_sp)
{
- data_sp = ReadMemory (process_sp, m_offset, header_and_lc_size);
+ data_sp = ReadMemory (process_sp, m_memory_addr, header_and_lc_size);
}
else
{
// Read in all only the load command data from the file on disk
- data_sp = m_file.ReadFileContents(m_offset, header_and_lc_size);
+ data_sp = m_file.ReadFileContents(m_file_offset, header_and_lc_size);
if (data_sp->GetByteSize() != header_and_lc_size)
return false;
}
@@ -613,7 +640,7 @@ ObjectFileMachO::IsExecutable() const
return m_header.filetype == HeaderFileTypeExecutable;
}
-size_t
+uint32_t
ObjectFileMachO::GetAddressByteSize () const
{
return m_data.GetAddressByteSize ();
@@ -682,15 +709,16 @@ ObjectFileMachO::GetAddressClass (lldb::
}
}
}
-
+
const SymbolType symbol_type = symbol->GetType();
switch (symbol_type)
{
case eSymbolTypeAny: return eAddressClassUnknown;
case eSymbolTypeAbsolute: return eAddressClassUnknown;
-
+
case eSymbolTypeCode:
case eSymbolTypeTrampoline:
+ case eSymbolTypeResolver:
if (m_header.cputype == llvm::MachO::CPUTypeARM)
{
// For ARM we have a bit in the n_desc field of the symbol
@@ -770,7 +798,7 @@ ObjectFileMachO::ParseSections ()
{
lldb::user_id_t segID = 0;
lldb::user_id_t sectID = 0;
- uint32_t offset = MachHeaderSizeFromMagic(m_header.magic);
+ lldb::offset_t offset = MachHeaderSizeFromMagic(m_header.magic);
uint32_t i;
const bool is_core = GetType() == eTypeCoreFile;
//bool dump_sections = false;
@@ -781,10 +809,10 @@ ObjectFileMachO::ParseSections ()
encryption_info_command encryption_cmd;
for (i=0; i<m_header.ncmds; ++i)
{
- const uint32_t load_cmd_offset = offset;
+ const lldb::offset_t load_cmd_offset = offset;
if (m_data.GetU32(&offset, &encryption_cmd, 2) == NULL)
break;
-
+
if (encryption_cmd.cmd == LoadCommandEncryptionInfo)
{
if (m_data.GetU32(&offset, &encryption_cmd.cryptoff, 3))
@@ -806,7 +834,7 @@ ObjectFileMachO::ParseSections ()
struct segment_command_64 load_cmd;
for (i=0; i<m_header.ncmds; ++i)
{
- const uint32_t load_cmd_offset = offset;
+ const lldb::offset_t load_cmd_offset = offset;
if (m_data.GetU32(&offset, &load_cmd, 2) == NULL)
break;
@@ -818,16 +846,41 @@ ObjectFileMachO::ParseSections ()
load_cmd.vmsize = m_data.GetAddress(&offset);
load_cmd.fileoff = m_data.GetAddress(&offset);
load_cmd.filesize = m_data.GetAddress(&offset);
+ if (m_length != 0 && load_cmd.filesize != 0)
+ {
+ if (load_cmd.fileoff + load_cmd.filesize > m_length)
+ {
+ // We have a load command that says it extends past the end of hte file. This is likely
+ // a corrupt file. We don't have any way to return an error condition here (this method
+ // was likely invokved from something like ObjectFile::GetSectionList()) -- all we can do
+ // is null out the SectionList vector and if a process has been set up, dump a message
+ // to stdout. The most common case here is core file debugging with a truncated file - and
+ // in that case we don't have a Process yet so nothing will be printed. Not really ideal;
+ // the ObjectFile needs some way of reporting an error message for methods like GetSectionList
+ // which fail.
+ ProcessSP process_sp (m_process_wp.lock());
+ if (process_sp)
+ {
+ Stream *s = &process_sp->GetTarget().GetDebugger().GetOutputStream();
+ if (s)
+ {
+ s->Printf ("Corrupt/invalid Mach-O object file -- a load command extends past the end of the file.\n");
+ }
+ }
+ m_sections_ap->Clear();
+ return 0;
+ }
+ }
if (m_data.GetU32(&offset, &load_cmd.maxprot, 4))
{
-
+
const bool segment_is_encrypted = (load_cmd.flags & SegmentCommandFlagBitProtectedVersion1) != 0;
// Keep a list of mach segments around in case we need to
// get at data that isn't stored in the abstracted Sections.
m_mach_segments.push_back (load_cmd);
- ConstString segment_name (load_cmd.segname, std::min<int>(strlen(load_cmd.segname), sizeof(load_cmd.segname)));
+ ConstString segment_name (load_cmd.segname, std::min<size_t>(strlen(load_cmd.segname), sizeof(load_cmd.segname)));
// Use a segment ID of the segment index shifted left by 8 so they
// never conflict with any of the sections.
SectionSP segment_sp;
@@ -850,7 +903,7 @@ ObjectFileMachO::ParseSections ()
struct section_64 sect64;
::memset (§64, 0, sizeof(sect64));
// Push a section into our mach sections for the section at
- // index zero (NListSectionNoSection) if we don't have any
+ // index zero (NListSectionNoSection) if we don't have any
// mach sections yet...
if (m_mach_sections.empty())
m_mach_sections.push_back(sect64);
@@ -1031,11 +1084,11 @@ ObjectFileMachO::ParseSections ()
// TODO: categorize sections by other flags for regular sections
case SectionTypeRegular:
if (segment_sp->GetName() == g_sect_name_TEXT)
- sect_type = eSectionTypeCode;
+ sect_type = eSectionTypeCode;
else if (segment_sp->GetName() == g_sect_name_DATA)
- sect_type = eSectionTypeData;
+ sect_type = eSectionTypeData;
else
- sect_type = eSectionTypeOther;
+ sect_type = eSectionTypeOther;
break;
case SectionTypeZeroFill: sect_type = eSectionTypeZeroFill; break;
case SectionTypeCStringLiterals: sect_type = eSectionTypeDataCString; break; // section with only literal C strings
@@ -1068,7 +1121,7 @@ ObjectFileMachO::ParseSections ()
sect64.offset == 0 ? 0 : sect64.size,
sect64.flags));
// Set the section to be encrypted to match the segment
-
+
bool section_is_encrypted = false;
if (!segment_is_encrypted && load_cmd.filesize != 0)
section_is_encrypted = encrypted_file_ranges.FindEntryThatContains(sect64.offset) != NULL;
@@ -1210,14 +1263,14 @@ ObjectFileMachO::ParseSymtab (bool minim
struct linkedit_data_command function_starts_load_command = { 0, 0, 0, 0 };
typedef AddressDataArray<lldb::addr_t, bool, 100> FunctionStarts;
FunctionStarts function_starts;
- uint32_t offset = MachHeaderSizeFromMagic(m_header.magic);
+ lldb::offset_t offset = MachHeaderSizeFromMagic(m_header.magic);
uint32_t i;
- LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_SYMBOLS));
+ Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_SYMBOLS));
for (i=0; i<m_header.ncmds; ++i)
{
- const uint32_t cmd_offset = offset;
+ const lldb::offset_t cmd_offset = offset;
// Read in the load command and load command size
struct load_command lc;
if (m_data.GetU32(&offset, &lc, 2) == NULL)
@@ -1234,28 +1287,28 @@ ObjectFileMachO::ParseSymtab (bool minim
if (symtab_load_command.symoff == 0)
{
if (log)
- module_sp->LogMessage(log.get(), "LC_SYMTAB.symoff == 0");
+ module_sp->LogMessage(log, "LC_SYMTAB.symoff == 0");
return 0;
}
if (symtab_load_command.stroff == 0)
{
if (log)
- module_sp->LogMessage(log.get(), "LC_SYMTAB.stroff == 0");
+ module_sp->LogMessage(log, "LC_SYMTAB.stroff == 0");
return 0;
}
-
+
if (symtab_load_command.nsyms == 0)
{
if (log)
- module_sp->LogMessage(log.get(), "LC_SYMTAB.nsyms == 0");
+ module_sp->LogMessage(log, "LC_SYMTAB.nsyms == 0");
return 0;
}
-
+
if (symtab_load_command.strsize == 0)
{
if (log)
- module_sp->LogMessage(log.get(), "LC_SYMTAB.strsize == 0");
+ module_sp->LogMessage(log, "LC_SYMTAB.strsize == 0");
return 0;
}
break;
@@ -1283,14 +1336,16 @@ ObjectFileMachO::ParseSymtab (bool minim
ProcessSP process_sp (m_process_wp.lock());
Process *process = process_sp.get();
- const size_t addr_byte_size = m_data.GetAddressByteSize();
+ const uint32_t addr_byte_size = m_data.GetAddressByteSize();
+ const ByteOrder byte_order = m_data.GetByteOrder();
bool bit_width_32 = addr_byte_size == 4;
const size_t nlist_byte_size = bit_width_32 ? sizeof(struct nlist) : sizeof(struct nlist_64);
- DataExtractor nlist_data (NULL, 0, m_data.GetByteOrder(), m_data.GetAddressByteSize());
- DataExtractor strtab_data (NULL, 0, m_data.GetByteOrder(), m_data.GetAddressByteSize());
- DataExtractor function_starts_data (NULL, 0, m_data.GetByteOrder(), m_data.GetAddressByteSize());
-
+ DataExtractor nlist_data (NULL, 0, byte_order, addr_byte_size);
+ DataExtractor strtab_data (NULL, 0, byte_order, addr_byte_size);
+ DataExtractor function_starts_data (NULL, 0, byte_order, addr_byte_size);
+ DataExtractor indirect_symbol_index_data (NULL, 0, byte_order, addr_byte_size);
+
const addr_t nlist_data_byte_size = symtab_load_command.nsyms * nlist_byte_size;
const addr_t strtab_data_byte_size = symtab_load_command.strsize;
addr_t strtab_addr = LLDB_INVALID_ADDRESS;
@@ -1326,8 +1381,17 @@ ObjectFileMachO::ParseSymtab (bool minim
// symbol and string table. Reading all of this symbol and string table
// data across can slow down debug launch times, so we optimize this by
// reading the memory for the __LINKEDIT section from this process.
+
+ UUID lldb_shared_cache(GetLLDBSharedCacheUUID());
+ UUID process_shared_cache(GetProcessSharedCacheUUID(process));
+ bool use_lldb_cache = true;
+ if (lldb_shared_cache.IsValid() && process_shared_cache.IsValid() && lldb_shared_cache != process_shared_cache)
+ {
+ use_lldb_cache = false;
+ }
+
PlatformSP platform_sp (target.GetPlatform());
- if (platform_sp && platform_sp->IsHost())
+ if (platform_sp && platform_sp->IsHost() && use_lldb_cache)
{
data_was_read = true;
nlist_data.SetData((void *)symoff_addr, nlist_data_byte_size, eByteOrderLittle);
@@ -1349,6 +1413,13 @@ ObjectFileMachO::ParseSymtab (bool minim
//DataBufferSP strtab_data_sp (ReadMemory (process_sp, strtab_addr, strtab_data_byte_size));
//if (strtab_data_sp)
// strtab_data.SetData (strtab_data_sp, 0, strtab_data_sp->GetByteSize());
+ if (m_dysymtab.nindirectsyms != 0)
+ {
+ const addr_t indirect_syms_addr = linkedit_load_addr + m_dysymtab.indirectsymoff - linkedit_file_offset;
+ DataBufferSP indirect_syms_data_sp (ReadMemory (process_sp, indirect_syms_addr, m_dysymtab.nindirectsyms * 4));
+ if (indirect_syms_data_sp)
+ indirect_symbol_index_data.SetData (indirect_syms_data_sp, 0, indirect_syms_data_sp->GetByteSize());
+ }
if (function_starts_load_command.cmd)
{
const addr_t func_start_addr = linkedit_load_addr + function_starts_load_command.dataoff - linkedit_file_offset;
@@ -1361,12 +1432,18 @@ ObjectFileMachO::ParseSymtab (bool minim
}
else
{
- nlist_data.SetData (m_data,
- symtab_load_command.symoff,
+ nlist_data.SetData (m_data,
+ symtab_load_command.symoff,
nlist_data_byte_size);
strtab_data.SetData (m_data,
- symtab_load_command.stroff,
+ symtab_load_command.stroff,
strtab_data_byte_size);
+ if (m_dysymtab.nindirectsyms != 0)
+ {
+ indirect_symbol_index_data.SetData (m_data,
+ m_dysymtab.indirectsymoff,
+ m_dysymtab.nindirectsyms * 4);
+ }
if (function_starts_load_command.cmd)
{
function_starts_data.SetData (m_data,
@@ -1378,7 +1455,7 @@ ObjectFileMachO::ParseSymtab (bool minim
if (nlist_data.GetByteSize() == 0)
{
if (log)
- module_sp->LogMessage(log.get(), "failed to read nlist data");
+ module_sp->LogMessage(log, "failed to read nlist data");
return 0;
}
@@ -1391,14 +1468,14 @@ ObjectFileMachO::ParseSymtab (bool minim
if (strtab_addr == LLDB_INVALID_ADDRESS)
{
if (log)
- module_sp->LogMessage(log.get(), "failed to locate the strtab in memory");
+ module_sp->LogMessage(log, "failed to locate the strtab in memory");
return 0;
}
}
else
{
if (log)
- module_sp->LogMessage(log.get(), "failed to read strtab data");
+ module_sp->LogMessage(log, "failed to read strtab data");
return 0;
}
}
@@ -1417,11 +1494,22 @@ ObjectFileMachO::ParseSymtab (bool minim
eh_frame_section_sp = section_list->FindSectionByName (g_section_name_eh_frame);
const bool is_arm = (m_header.cputype == llvm::MachO::CPUTypeARM);
+
+ // lldb works best if it knows the start addresss of all functions in a module.
+ // Linker symbols or debug info are normally the best source of information for start addr / size but
+ // they may be stripped in a released binary.
+ // Two additional sources of information exist in Mach-O binaries:
+ // LC_FUNCTION_STARTS - a list of ULEB128 encoded offsets of each function's start address in the
+ // binary, relative to the text section.
+ // eh_frame - the eh_frame FDEs have the start addr & size of each function
+ // LC_FUNCTION_STARTS is the fastest source to read in, and is present on all modern binaries.
+ // Binaries built to run on older releases may need to use eh_frame information.
+
if (text_section_sp && function_starts_data.GetByteSize())
{
FunctionStarts::Entry function_start_entry;
function_start_entry.data = false;
- uint32_t function_start_offset = 0;
+ lldb::offset_t function_start_offset = 0;
function_start_entry.addr = text_section_sp->GetFileAddress();
uint64_t delta;
while ((delta = function_starts_data.GetULEB128(&function_start_offset)) > 0)
@@ -1431,12 +1519,37 @@ ObjectFileMachO::ParseSymtab (bool minim
function_starts.Append(function_start_entry);
}
}
-
- const uint32_t function_starts_count = function_starts.GetSize();
+ else
+ {
+ // If m_type is eTypeDebugInfo, then this is a dSYM - it will have the load command claiming an eh_frame
+ // but it doesn't actually have the eh_frame content. And if we have a dSYM, we don't need to do any
+ // of this fill-in-the-missing-symbols works anyway - the debug info should give us all the functions in
+ // the module.
+ if (text_section_sp.get() && eh_frame_section_sp.get() && m_type != eTypeDebugInfo)
+ {
+ DWARFCallFrameInfo eh_frame(*this, eh_frame_section_sp, eRegisterKindGCC, true);
+ DWARFCallFrameInfo::FunctionAddressAndSizeVector functions;
+ eh_frame.GetFunctionAddressAndSizeVector (functions);
+ addr_t text_base_addr = text_section_sp->GetFileAddress();
+ size_t count = functions.GetSize();
+ for (size_t i = 0; i < count; ++i)
+ {
+ const DWARFCallFrameInfo::FunctionAddressAndSizeVector::Entry *func = functions.GetEntryAtIndex (i);
+ if (func)
+ {
+ FunctionStarts::Entry function_start_entry;
+ function_start_entry.addr = func->base - text_base_addr;
+ function_starts.Append(function_start_entry);
+ }
+ }
+ }
+ }
- uint8_t TEXT_eh_frame_sectID = eh_frame_section_sp.get() ? eh_frame_section_sp->GetID() : NListSectionNoSection;
+ const size_t function_starts_count = function_starts.GetSize();
- uint32_t nlist_data_offset = 0;
+ const user_id_t TEXT_eh_frame_sectID = eh_frame_section_sp.get() ? eh_frame_section_sp->GetID() : NListSectionNoSection;
+
+ lldb::offset_t nlist_data_offset = 0;
uint32_t N_SO_index = UINT32_MAX;
@@ -1458,7 +1571,7 @@ ObjectFileMachO::ParseSymtab (bool minim
uint32_t sym_idx = 0;
Symbol *sym = NULL;
- uint32_t num_syms = 0;
+ size_t num_syms = 0;
std::string memory_symbol_name;
uint32_t unmapped_local_symbols_found = 0;
@@ -1476,58 +1589,74 @@ ObjectFileMachO::ParseSymtab (bool minim
// Before we can start mapping the DSC, we need to make certain the target process is actually
// using the cache we can find.
- /*
- * TODO (FIXME!)
- *
- * Consider the case of testing with a separate DSC file.
- * If we go through the normal code paths, we will give symbols for the wrong DSC, and
- * that is bad. We need to read the target process' all_image_infos struct, and look
- * at the values of the processDetachedFromSharedRegion field. If that is set, we should skip
- * this code section.
- */
-
// Next we need to determine the correct path for the dyld shared cache.
ArchSpec header_arch(eArchTypeMachO, m_header.cputype, m_header.cpusubtype);
char dsc_path[PATH_MAX];
snprintf(dsc_path, sizeof(dsc_path), "%s%s%s",
- "/System/Library/Caches/com.apple.dyld/", /* IPHONE_DYLD_SHARED_CACHE_DIR */
- "dyld_shared_cache_", /* DYLD_SHARED_CACHE_BASE_NAME */
+ "/System/Library/Caches/com.apple.dyld/", /* IPHONE_DYLD_SHARED_CACHE_DIR */
+ "dyld_shared_cache_", /* DYLD_SHARED_CACHE_BASE_NAME */
header_arch.GetArchitectureName());
FileSpec dsc_filespec(dsc_path, false);
// We need definitions of two structures in the on-disk DSC, copy them here manually
- struct lldb_copy_dyld_cache_header
+ struct lldb_copy_dyld_cache_header_v0
{
- char magic[16];
- uint32_t mappingOffset;
- uint32_t mappingCount;
- uint32_t imagesOffset;
- uint32_t imagesCount;
- uint64_t dyldBaseAddress;
- uint64_t codeSignatureOffset;
- uint64_t codeSignatureSize;
- uint64_t slideInfoOffset;
- uint64_t slideInfoSize;
- uint64_t localSymbolsOffset;
- uint64_t localSymbolsSize;
+ char magic[16]; // e.g. "dyld_v0 i386", "dyld_v1 armv7", etc.
+ uint32_t mappingOffset; // file offset to first dyld_cache_mapping_info
+ uint32_t mappingCount; // number of dyld_cache_mapping_info entries
+ uint32_t imagesOffset;
+ uint32_t imagesCount;
+ uint64_t dyldBaseAddress;
+ uint64_t codeSignatureOffset;
+ uint64_t codeSignatureSize;
+ uint64_t slideInfoOffset;
+ uint64_t slideInfoSize;
+ uint64_t localSymbolsOffset; // file offset of where local symbols are stored
+ uint64_t localSymbolsSize; // size of local symbols information
};
+ struct lldb_copy_dyld_cache_header_v1
+ {
+ char magic[16]; // e.g. "dyld_v0 i386", "dyld_v1 armv7", etc.
+ uint32_t mappingOffset; // file offset to first dyld_cache_mapping_info
+ uint32_t mappingCount; // number of dyld_cache_mapping_info entries
+ uint32_t imagesOffset;
+ uint32_t imagesCount;
+ uint64_t dyldBaseAddress;
+ uint64_t codeSignatureOffset;
+ uint64_t codeSignatureSize;
+ uint64_t slideInfoOffset;
+ uint64_t slideInfoSize;
+ uint64_t localSymbolsOffset;
+ uint64_t localSymbolsSize;
+ uint8_t uuid[16]; // v1 and above, also recorded in dyld_all_image_infos v13 and later
+ };
+
+ struct lldb_copy_dyld_cache_mapping_info
+ {
+ uint64_t address;
+ uint64_t size;
+ uint64_t fileOffset;
+ uint32_t maxProt;
+ uint32_t initProt;
+ };
+
struct lldb_copy_dyld_cache_local_symbols_info
{
- uint32_t nlistOffset;
- uint32_t nlistCount;
- uint32_t stringsOffset;
- uint32_t stringsSize;
- uint32_t entriesOffset;
- uint32_t entriesCount;
+ uint32_t nlistOffset;
+ uint32_t nlistCount;
+ uint32_t stringsOffset;
+ uint32_t stringsSize;
+ uint32_t entriesOffset;
+ uint32_t entriesCount;
};
struct lldb_copy_dyld_cache_local_symbols_entry
{
- uint32_t dylibOffset;
- uint32_t nlistStartIndex;
- uint32_t nlistCount;
+ uint32_t dylibOffset;
+ uint32_t nlistStartIndex;
+ uint32_t nlistCount;
};
/* The dyld_cache_header has a pointer to the dyld_cache_local_symbols_info structure (localSymbolsOffset).
@@ -1538,7 +1667,7 @@ ObjectFileMachO::ParseSymtab (bool minim
There is one dyld_cache_local_symbols_entry per dylib/framework in the dyld shared cache.
The "dylibOffset" field is the Mach-O header of this dylib/framework in the dyld shared cache.
- The dyld_cache_local_symbols_entry also lists the start of this dylib/framework's nlist records
+ The dyld_cache_local_symbols_entry also lists the start of this dylib/framework's nlist records
and the count of how many nlist records there are for this dylib/framework.
*/
@@ -1546,28 +1675,78 @@ ObjectFileMachO::ParseSymtab (bool minim
//
// Save some VM space, do not map the entire cache in one shot.
- if (DataBufferSP dsc_data_sp = dsc_filespec.MemoryMapFileContents(0, sizeof(struct lldb_copy_dyld_cache_header)))
+ DataBufferSP dsc_data_sp;
+ dsc_data_sp = dsc_filespec.MemoryMapFileContents(0, sizeof(struct lldb_copy_dyld_cache_header_v1));
+
+ if (dsc_data_sp)
{
- DataExtractor dsc_header_data(dsc_data_sp, m_data.GetByteOrder(), m_data.GetAddressByteSize());
+ DataExtractor dsc_header_data(dsc_data_sp, byte_order, addr_byte_size);
+
+ char version_str[17];
+ int version = -1;
+ lldb::offset_t offset = 0;
+ memcpy (version_str, dsc_header_data.GetData (&offset, 16), 16);
+ version_str[16] = '\0';
+ if (strncmp (version_str, "dyld_v", 6) == 0 && isdigit (version_str[6]))
+ {
+ int v;
+ if (::sscanf (version_str + 6, "%d", &v) == 1)
+ {
+ version = v;
+ }
+ }
+
+ UUID dsc_uuid;
+ if (version >= 1)
+ {
+ offset = offsetof (struct lldb_copy_dyld_cache_header_v1, uuid);
+ uint8_t uuid_bytes[sizeof (uuid_t)];
+ memcpy (uuid_bytes, dsc_header_data.GetData (&offset, sizeof (uuid_t)), sizeof (uuid_t));
+ dsc_uuid.SetBytes (uuid_bytes);
+ }
+
+ bool uuid_match = true;
+ if (dsc_uuid.IsValid() && process)
+ {
+ UUID shared_cache_uuid(GetProcessSharedCacheUUID(process));
+
+ if (shared_cache_uuid.IsValid() && dsc_uuid != shared_cache_uuid)
+ {
+ // The on-disk dyld_shared_cache file is not the same as the one in this
+ // process' memory, don't use it.
+ uuid_match = false;
+ }
+ }
+
+ offset = offsetof (struct lldb_copy_dyld_cache_header_v1, mappingOffset);
- uint32_t offset = offsetof (struct lldb_copy_dyld_cache_header, mappingOffset);
uint32_t mappingOffset = dsc_header_data.GetU32(&offset);
// If the mappingOffset points to a location inside the header, we've
// opened an old dyld shared cache, and should not proceed further.
- if (mappingOffset >= sizeof(struct lldb_copy_dyld_cache_header))
+ if (uuid_match && mappingOffset >= sizeof(struct lldb_copy_dyld_cache_header_v0))
{
- offset = offsetof (struct lldb_copy_dyld_cache_header, localSymbolsOffset);
+ DataBufferSP dsc_mapping_info_data_sp = dsc_filespec.MemoryMapFileContents(mappingOffset, sizeof (struct lldb_copy_dyld_cache_mapping_info));
+ DataExtractor dsc_mapping_info_data(dsc_mapping_info_data_sp, byte_order, addr_byte_size);
+ offset = 0;
+
+ // The File addresses (from the in-memory Mach-O load commands) for the shared libraries
+ // in the shared library cache need to be adjusted by an offset to match up with the
+ // dylibOffset identifying field in the dyld_cache_local_symbol_entry's. This offset is
+ // recorded in mapping_offset_value.
+ const uint64_t mapping_offset_value = dsc_mapping_info_data.GetU64(&offset);
+
+ offset = offsetof (struct lldb_copy_dyld_cache_header_v1, localSymbolsOffset);
uint64_t localSymbolsOffset = dsc_header_data.GetU64(&offset);
uint64_t localSymbolsSize = dsc_header_data.GetU64(&offset);
- if (localSymbolsOffset && localSymbolsSize)
+ if (localSymbolsOffset && localSymbolsSize)
{
// Map the local symbols
- if (DataBufferSP dsc_local_symbols_data_sp = dsc_filespec.MemoryMapFileContents(localSymbolsOffset, localSymbolsSize))
+ if (DataBufferSP dsc_local_symbols_data_sp = dsc_filespec.MemoryMapFileContents(localSymbolsOffset, localSymbolsSize))
{
- DataExtractor dsc_local_symbols_data(dsc_local_symbols_data_sp, m_data.GetByteOrder(), m_data.GetAddressByteSize());
+ DataExtractor dsc_local_symbols_data(dsc_local_symbols_data_sp, byte_order, addr_byte_size);
offset = 0;
@@ -1575,14 +1754,9 @@ ObjectFileMachO::ParseSymtab (bool minim
struct lldb_copy_dyld_cache_local_symbols_info local_symbols_info;
dsc_local_symbols_data.GetU32(&offset, &local_symbols_info.nlistOffset, 6);
- // The local_symbols_infos offsets are offsets into local symbols memory, NOT file offsets!
- // We first need to identify the local "entry" that matches the current header.
- // The "entry" is stored as a file offset in the dyld_shared_cache, so we need to
- // adjust the raw m_header value by slide and 0x30000000.
-
SectionSP text_section_sp(section_list->FindSectionByName(GetSegmentNameTEXT()));
- uint32_t header_file_offset = (text_section_sp->GetFileAddress() - 0x30000000);
+ uint32_t header_file_offset = (text_section_sp->GetFileAddress() - mapping_offset_value);
offset = local_symbols_info.entriesOffset;
for (uint32_t entry_index = 0; entry_index < local_symbols_info.entriesCount; entry_index++)
@@ -1592,7 +1766,7 @@ ObjectFileMachO::ParseSymtab (bool minim
local_symbols_entry.nlistStartIndex = dsc_local_symbols_data.GetU32(&offset);
local_symbols_entry.nlistCount = dsc_local_symbols_data.GetU32(&offset);
- if (header_file_offset == local_symbols_entry.dylibOffset)
+ if (header_file_offset == local_symbols_entry.dylibOffset)
{
unmapped_local_symbols_found = local_symbols_entry.nlistCount;
@@ -1603,7 +1777,7 @@ ObjectFileMachO::ParseSymtab (bool minim
nlist_data_offset = local_symbols_info.nlistOffset + (nlist_byte_size * local_symbols_entry.nlistStartIndex);
uint32_t string_table_offset = local_symbols_info.stringsOffset;
- for (uint32_t nlist_index = 0; nlist_index < local_symbols_entry.nlistCount; nlist_index++)
+ for (uint32_t nlist_index = 0; nlist_index < local_symbols_entry.nlistCount; nlist_index++)
{
/////////////////////////////
{
@@ -2054,7 +2228,7 @@ ObjectFileMachO::ParseSymtab (bool minim
else
{
uint32_t section_type = symbol_section->Get() & SectionFlagMaskSectionType;
-
+
switch (section_type)
{
case SectionTypeRegular: break; // regular section
@@ -2076,7 +2250,7 @@ ObjectFileMachO::ParseSymtab (bool minim
case SectionTypeLazyDylibSymbolPointers: type = eSymbolTypeTrampoline; break;
default: break;
}
-
+
if (type == eSymbolTypeInvalid)
{
const char *symbol_sect_name = symbol_section->GetName().AsCString();
@@ -2094,7 +2268,7 @@ ObjectFileMachO::ParseSymtab (bool minim
if (symbol_sect_name && ::strstr (symbol_sect_name, "__objc") == symbol_sect_name)
{
type = eSymbolTypeRuntime;
-
+
if (symbol_name &&
symbol_name[0] == '_' &&
symbol_name[1] == 'O' &&
@@ -2160,14 +2334,14 @@ ObjectFileMachO::ParseSymtab (bool minim
}
}
break;
- }
+ }
}
if (add_nlist)
{
uint64_t symbol_value = nlist.n_value;
bool symbol_name_is_mangled = false;
-
+
if (symbol_name_non_abi_mangled)
{
sym[sym_idx].GetMangled().SetMangledName (ConstString(symbol_name_non_abi_mangled));
@@ -2180,13 +2354,13 @@ ObjectFileMachO::ParseSymtab (bool minim
symbol_name_is_mangled = symbol_name[1] == '_';
symbol_name++; // Skip the leading underscore
}
-
+
if (symbol_name)
{
sym[sym_idx].GetMangled().SetValue(ConstString(symbol_name), symbol_name_is_mangled);
}
}
-
+
if (is_debug == false)
{
if (type == eSymbolTypeCode)
@@ -2255,7 +2429,7 @@ ObjectFileMachO::ParseSymtab (bool minim
if (func_start_entry)
{
func_start_entry->data = true;
-
+
addr_t symbol_file_addr = func_start_entry->addr;
uint32_t symbol_flags = 0;
if (is_arm)
@@ -2264,7 +2438,7 @@ ObjectFileMachO::ParseSymtab (bool minim
symbol_flags = MACHO_NLIST_ARM_SYMBOL_IS_THUMB;
symbol_file_addr &= 0xfffffffffffffffeull;
}
-
+
const FunctionStarts::Entry *next_func_start_entry = function_starts.FindNextEntry (func_start_entry);
const addr_t section_end_file_addr = section_file_addr + symbol_section->GetByteSize();
if (next_func_start_entry)
@@ -2284,13 +2458,13 @@ ObjectFileMachO::ParseSymtab (bool minim
}
symbol_value -= section_file_addr;
}
-
+
sym[sym_idx].SetID (nlist_idx);
sym[sym_idx].SetType (type);
sym[sym_idx].GetAddress().SetSection (symbol_section);
sym[sym_idx].GetAddress().SetOffset (symbol_value);
sym[sym_idx].SetFlags (nlist.n_type << 16 | nlist.n_desc);
-
+
if (symbol_byte_size > 0)
sym[sym_idx].SetByteSize(symbol_byte_size);
@@ -2302,7 +2476,7 @@ ObjectFileMachO::ParseSymtab (bool minim
{
sym[sym_idx].Clear();
}
-
+
}
/////////////////////////////
}
@@ -2352,18 +2526,18 @@ ObjectFileMachO::ParseSymtab (bool minim
SymbolType type = eSymbolTypeInvalid;
const char *symbol_name = NULL;
-
+
if (have_strtab_data)
{
symbol_name = strtab_data.PeekCStr(nlist.n_strx);
-
+
if (symbol_name == NULL)
{
// No symbol should be NULL, even the symbols with no
// string values should have an offset zero which points
// to an empty C-string
Host::SystemLog (Host::eSystemLogError,
- "error: symbol[%u] has invalid string table offset 0x%x in %s/%s, ignoring symbol\n",
+ "error: symbol[%u] has invalid string table offset 0x%x in %s/%s, ignoring symbol\n",
nlist_idx,
nlist.n_strx,
module_sp->GetFileSpec().GetDirectory().GetCString(),
@@ -2383,7 +2557,7 @@ ObjectFileMachO::ParseSymtab (bool minim
const char *symbol_name_non_abi_mangled = NULL;
SectionSP symbol_section;
- uint32_t symbol_byte_size = 0;
+ lldb::addr_t symbol_byte_size = 0;
bool add_nlist = true;
bool is_debug = ((nlist.n_type & NlistMaskStab) != 0);
bool demangled_is_synthesized = false;
@@ -2396,18 +2570,18 @@ ObjectFileMachO::ParseSymtab (bool minim
{
switch (nlist.n_type)
{
- case StabGlobalSymbol:
+ case StabGlobalSymbol:
// N_GSYM -- global symbol: name,,NO_SECT,type,0
// Sometimes the N_GSYM value contains the address.
-
+
// FIXME: In the .o files, we have a GSYM and a debug symbol for all the ObjC data. They
// have the same address, but we want to ensure that we always find only the real symbol,
// 'cause we don't currently correctly attribute the GSYM one to the ObjCClass/Ivar/MetaClass
// symbol type. This is a temporary hack to make sure the ObjectiveC symbols get treated
// correctly. To do this right, we should coalesce all the GSYM & global symbols that have the
// same address.
-
- if (symbol_name && symbol_name[0] == '_' && symbol_name[1] == 'O'
+
+ if (symbol_name && symbol_name[0] == '_' && symbol_name[1] == 'O'
&& (strncmp (symbol_name, "_OBJC_IVAR_$_", strlen ("_OBJC_IVAR_$_")) == 0
|| strncmp (symbol_name, "_OBJC_CLASS_$_", strlen ("_OBJC_CLASS_$_")) == 0
|| strncmp (symbol_name, "_OBJC_METACLASS_$_", strlen ("_OBJC_METACLASS_$_")) == 0))
@@ -2426,13 +2600,13 @@ ObjectFileMachO::ParseSymtab (bool minim
type = eSymbolTypeCompiler;
break;
- case StabFunction:
+ case StabFunction:
// N_FUN -- procedure: name,,n_sect,linenumber,address
if (symbol_name)
{
type = eSymbolTypeCode;
symbol_section = section_info.GetSection (nlist.n_sect, nlist.n_value);
-
+
N_FUN_addr_to_sym_idx[nlist.n_value] = sym_idx;
// We use the current number of symbols in the symbol table in lieu of
// using nlist_idx in case we ever start trimming entries out
@@ -2457,7 +2631,7 @@ ObjectFileMachO::ParseSymtab (bool minim
}
break;
- case StabStaticSymbol:
+ case StabStaticSymbol:
// N_STSYM -- static symbol: name,,n_sect,type,address
N_STSYM_addr_to_sym_idx[nlist.n_value] = sym_idx;
symbol_section = section_info.GetSection (nlist.n_sect, nlist.n_value);
@@ -2617,7 +2791,7 @@ ObjectFileMachO::ParseSymtab (bool minim
N_SO_index = sym_idx;
}
}
-
+
break;
case StabObjectFileName:
@@ -2665,7 +2839,7 @@ ObjectFileMachO::ParseSymtab (bool minim
add_nlist = false;
break;
- case StabCompilerParameters:
+ case StabCompilerParameters:
// N_PARAMS - compiler parameters: name,,NO_SECT,0,0
type = eSymbolTypeCompiler;
break;
@@ -2827,8 +3001,8 @@ ObjectFileMachO::ParseSymtab (bool minim
const char *symbol_sect_name = symbol_section->GetName().AsCString();
if (symbol_section->IsDescendant (text_section_sp.get()))
{
- if (symbol_section->IsClear(SectionAttrUserPureInstructions |
- SectionAttrUserSelfModifyingCode |
+ if (symbol_section->IsClear(SectionAttrUserPureInstructions |
+ SectionAttrUserSelfModifyingCode |
SectionAttrSytemSomeInstructions))
type = eSymbolTypeData;
else
@@ -2841,9 +3015,9 @@ ObjectFileMachO::ParseSymtab (bool minim
{
type = eSymbolTypeRuntime;
- if (symbol_name &&
- symbol_name[0] == '_' &&
- symbol_name[1] == 'O' &&
+ if (symbol_name &&
+ symbol_name[0] == '_' &&
+ symbol_name[1] == 'O' &&
symbol_name[2] == 'B')
{
llvm::StringRef symbol_name_ref(symbol_name);
@@ -2909,7 +3083,7 @@ ObjectFileMachO::ParseSymtab (bool minim
}
}
break;
- }
+ }
}
if (add_nlist)
@@ -3004,7 +3178,7 @@ ObjectFileMachO::ParseSymtab (bool minim
if (func_start_entry)
{
func_start_entry->data = true;
-
+
addr_t symbol_file_addr = func_start_entry->addr;
if (is_arm)
symbol_file_addr &= 0xfffffffffffffffeull;
@@ -3080,7 +3254,7 @@ ObjectFileMachO::ParseSymtab (bool minim
}
}
}
-
+
uint32_t synthetic_sym_id = symtab_load_command.nsyms;
if (function_starts_count > 0)
@@ -3092,7 +3266,7 @@ ObjectFileMachO::ParseSymtab (bool minim
if (function_starts.GetEntryRef (i).data == false)
++num_synthetic_function_symbols;
}
-
+
if (num_synthetic_function_symbols > 0)
{
if (num_syms < sym_idx + num_synthetic_function_symbols)
@@ -3168,8 +3342,6 @@ ObjectFileMachO::ParseSymtab (bool minim
// Now synthesize indirect symbols
if (m_dysymtab.nindirectsyms != 0)
{
- DataExtractor indirect_symbol_index_data (m_data, m_dysymtab.indirectsymoff, m_dysymtab.nindirectsyms * 4);
-
if (indirect_symbol_index_data.GetByteSize())
{
NListIndexToSymbolIndexMap::const_iterator end_index_pos = m_nlist_idx_to_sym_idx.end();
@@ -3192,7 +3364,7 @@ ObjectFileMachO::ParseSymtab (bool minim
{
const uint32_t symbol_stub_index = symbol_stub_index_offset + stub_idx;
const lldb::addr_t symbol_stub_addr = m_mach_sections[sect_idx].addr + (stub_idx * symbol_stub_byte_size);
- uint32_t symbol_stub_offset = symbol_stub_index * 4;
+ lldb::offset_t symbol_stub_offset = symbol_stub_index * 4;
if (indirect_symbol_index_data.ValidOffsetForDataOfSize(symbol_stub_offset, 4))
{
const uint32_t stub_sym_id = indirect_symbol_index_data.GetU32 (&symbol_stub_offset);
@@ -3207,10 +3379,10 @@ ObjectFileMachO::ParseSymtab (bool minim
// a current symbol index, so just look this up by index
stub_symbol = symtab->SymbolAtIndex (index_pos->second);
}
- else
+ else
{
// We need to lookup a symbol using the original nlist
- // symbol index since this index is coming from the
+ // symbol index since this index is coming from the
// S_SYMBOL_STUBS
stub_symbol = symtab->FindSymbolByID (stub_sym_id);
}
@@ -3300,32 +3472,32 @@ ObjectFileMachO::GetUUID (lldb_private::
{
lldb_private::Mutex::Locker locker(module_sp->GetMutex());
struct uuid_command load_cmd;
- uint32_t offset = MachHeaderSizeFromMagic(m_header.magic);
+ lldb::offset_t offset = MachHeaderSizeFromMagic(m_header.magic);
uint32_t i;
for (i=0; i<m_header.ncmds; ++i)
{
- const uint32_t cmd_offset = offset;
+ const lldb::offset_t cmd_offset = offset;
if (m_data.GetU32(&offset, &load_cmd, 2) == NULL)
break;
if (load_cmd.cmd == LoadCommandUUID)
{
const uint8_t *uuid_bytes = m_data.PeekData(offset, 16);
-
+
if (uuid_bytes)
{
// OpenCL on Mac OS X uses the same UUID for each of its object files.
// We pretend these object files have no UUID to prevent crashing.
-
+
const uint8_t opencl_uuid[] = { 0x8c, 0x8e, 0xb3, 0x9b,
0x3b, 0xa8,
0x4b, 0x16,
0xb6, 0xa4,
0x27, 0x63, 0xbb, 0x14, 0xf0, 0x0d };
-
+
if (!memcmp(uuid_bytes, opencl_uuid, 16))
return false;
-
+
uuid->SetBytes (uuid_bytes);
return true;
}
@@ -3347,7 +3519,7 @@ ObjectFileMachO::GetDependentModules (Fi
{
lldb_private::Mutex::Locker locker(module_sp->GetMutex());
struct load_command load_cmd;
- uint32_t offset = MachHeaderSizeFromMagic(m_header.magic);
+ lldb::offset_t offset = MachHeaderSizeFromMagic(m_header.magic);
const bool resolve_path = false; // Don't resolve the dependend file paths since they may not reside on this system
uint32_t i;
for (i=0; i<m_header.ncmds; ++i)
@@ -3389,23 +3561,23 @@ ObjectFileMachO::GetDependentModules (Fi
}
lldb_private::Address
-ObjectFileMachO::GetEntryPointAddress ()
+ObjectFileMachO::GetEntryPointAddress ()
{
// If the object file is not an executable it can't hold the entry point. m_entry_point_address
// is initialized to an invalid address, so we can just return that.
// If m_entry_point_address is valid it means we've found it already, so return the cached value.
-
+
if (!IsExecutable() || m_entry_point_address.IsValid())
return m_entry_point_address;
-
- // Otherwise, look for the UnixThread or Thread command. The data for the Thread command is given in
+
+ // Otherwise, look for the UnixThread or Thread command. The data for the Thread command is given in
// /usr/include/mach-o.h, but it is basically:
//
// uint32_t flavor - this is the flavor argument you would pass to thread_get_state
// uint32_t count - this is the count of longs in the thread state data
// struct XXX_thread_state state - this is the structure from <machine/thread_status.h> corresponding to the flavor.
// <repeat this trio>
- //
+ //
// So we just keep reading the various register flavors till we find the GPR one, then read the PC out of there.
// FIXME: We will need to have a "RegisterContext data provider" class at some point that can get all the registers
// out of data in this form & attach them to a given thread. That should underlie the MacOS X User process plugin,
@@ -3420,14 +3592,14 @@ ObjectFileMachO::GetEntryPointAddress ()
{
lldb_private::Mutex::Locker locker(module_sp->GetMutex());
struct load_command load_cmd;
- uint32_t offset = MachHeaderSizeFromMagic(m_header.magic);
+ lldb::offset_t offset = MachHeaderSizeFromMagic(m_header.magic);
uint32_t i;
lldb::addr_t start_address = LLDB_INVALID_ADDRESS;
bool done = false;
-
+
for (i=0; i<m_header.ncmds; ++i)
{
- const uint32_t cmd_offset = offset;
+ const lldb::offset_t cmd_offset = offset;
if (m_data.GetU32(&offset, &load_cmd, 2) == NULL)
break;
@@ -3445,7 +3617,7 @@ ObjectFileMachO::GetEntryPointAddress ()
// We've gotten off somehow, log and exit;
return m_entry_point_address;
}
-
+
switch (m_header.cputype)
{
case llvm::MachO::CPUTypeARM:
@@ -3503,10 +3675,10 @@ ObjectFileMachO::GetEntryPointAddress ()
// Go to the next load command:
offset = cmd_offset + load_cmd.cmdsize;
}
-
+
if (start_address != LLDB_INVALID_ADDRESS)
{
- // We got the start address from the load commands, so now resolve that address in the sections
+ // We got the start address from the load commands, so now resolve that address in the sections
// of this ObjectFile:
if (!m_entry_point_address.ResolveAddressUsingFileSections (start_address, GetSectionList()))
{
@@ -3517,9 +3689,9 @@ ObjectFileMachO::GetEntryPointAddress ()
{
// We couldn't read the UnixThread load command - maybe it wasn't there. As a fallback look for the
// "start" symbol in the main executable.
-
+
ModuleSP module_sp (GetModule());
-
+
if (module_sp)
{
SymbolContextList contexts;
@@ -3532,7 +3704,7 @@ ObjectFileMachO::GetEntryPointAddress ()
}
}
}
-
+
return m_entry_point_address;
}
@@ -3564,7 +3736,7 @@ ObjectFileMachO::GetNumThreadContexts ()
if (!m_thread_context_offsets_valid)
{
m_thread_context_offsets_valid = true;
- uint32_t offset = MachHeaderSizeFromMagic(m_header.magic);
+ lldb::offset_t offset = MachHeaderSizeFromMagic(m_header.magic);
FileRangeArray::Entry file_range;
thread_command thread_cmd;
for (uint32_t i=0; i<m_header.ncmds; ++i)
@@ -3572,7 +3744,7 @@ ObjectFileMachO::GetNumThreadContexts ()
const uint32_t cmd_offset = offset;
if (m_data.GetU32(&offset, &thread_cmd, 2) == NULL)
break;
-
+
if (thread_cmd.cmd == LoadCommandThread)
{
file_range.SetRangeBase (offset);
@@ -3601,9 +3773,9 @@ ObjectFileMachO::GetThreadContextAtIndex
const FileRangeArray::Entry *thread_context_file_range = m_thread_context_offsets.GetEntryAtIndex (idx);
if (thread_context_file_range)
{
-
- DataExtractor data (m_data,
- thread_context_file_range->GetRangeBase(),
+
+ DataExtractor data (m_data,
+ thread_context_file_range->GetRangeBase(),
thread_context_file_range->GetByteSize());
#if defined(__APPLE__)
switch (m_header.cputype)
@@ -3611,11 +3783,11 @@ ObjectFileMachO::GetThreadContextAtIndex
case llvm::MachO::CPUTypeARM:
reg_ctx_sp.reset (new RegisterContextDarwin_arm_Mach (thread, data));
break;
-
+
case llvm::MachO::CPUTypeI386:
reg_ctx_sp.reset (new RegisterContextDarwin_i386_Mach (thread, data));
break;
-
+
case llvm::MachO::CPUTypeX86_64:
reg_ctx_sp.reset (new RegisterContextDarwin_x86_64_Mach (thread, data));
break;
@@ -3643,7 +3815,7 @@ ObjectFileMachO::CalculateType()
if (GetUUID(&uuid))
{
// this checking for the UUID load command is not enough
- // we could eventually look for the symbol named
+ // we could eventually look for the symbol named
// "OSKextGetCurrentIdentifier" as this is required of kexts
if (m_strata == eStrataInvalid)
m_strata = eStrataKernel;
@@ -3681,7 +3853,7 @@ ObjectFileMachO::CalculateStrata()
if (GetUUID(&uuid))
{
// this checking for the UUID load command is not enough
- // we could eventually look for the symbol named
+ // we could eventually look for the symbol named
// "OSKextGetCurrentIdentifier" as this is required of kexts
if (m_type == eTypeInvalid)
m_type = eTypeSharedLibrary;
@@ -3697,7 +3869,7 @@ ObjectFileMachO::CalculateStrata()
{
return eStrataUser;
}
- else
+ else
{
SectionList *section_list = GetSectionList();
if (section_list)
@@ -3733,16 +3905,16 @@ ObjectFileMachO::GetVersion (uint32_t *v
{
lldb_private::Mutex::Locker locker(module_sp->GetMutex());
struct dylib_command load_cmd;
- uint32_t offset = MachHeaderSizeFromMagic(m_header.magic);
+ lldb::offset_t offset = MachHeaderSizeFromMagic(m_header.magic);
uint32_t version_cmd = 0;
uint64_t version = 0;
uint32_t i;
for (i=0; i<m_header.ncmds; ++i)
{
- const uint32_t cmd_offset = offset;
+ const lldb::offset_t cmd_offset = offset;
if (m_data.GetU32(&offset, &load_cmd, 2) == NULL)
break;
-
+
if (load_cmd.cmd == LoadCommandDylibIdent)
{
if (version_cmd == 0)
@@ -3752,12 +3924,12 @@ ObjectFileMachO::GetVersion (uint32_t *v
break;
version = load_cmd.dylib.current_version;
}
- break; // Break for now unless there is another more complete version
+ break; // Break for now unless there is another more complete version
// number load command in the future.
}
offset = cmd_offset + load_cmd.cmdsize;
}
-
+
if (version_cmd == LoadCommandDylibIdent)
{
if (versions != NULL && num_versions > 0)
@@ -3788,9 +3960,9 @@ ObjectFileMachO::GetArchitecture (ArchSp
{
lldb_private::Mutex::Locker locker(module_sp->GetMutex());
arch.SetArchitecture (eArchTypeMachO, m_header.cputype, m_header.cpusubtype);
-
+
// Files with type MH_PRELOAD are currently used in cases where the image
- // debugs at the addresses in the file itself. Below we set the OS to
+ // debugs at the addresses in the file itself. Below we set the OS to
// unknown to make sure we use the DynamicLoaderStatic()...
if (m_header.filetype == HeaderFileTypePreloadedExecutable)
{
@@ -3802,6 +3974,78 @@ ObjectFileMachO::GetArchitecture (ArchSp
}
+UUID
+ObjectFileMachO::GetProcessSharedCacheUUID (Process *process)
+{
+ UUID uuid;
+ if (process)
+ {
+ addr_t all_image_infos = process->GetImageInfoAddress();
+
+ // The address returned by GetImageInfoAddress may be the address of dyld (don't want)
+ // or it may be the address of the dyld_all_image_infos structure (want). The first four
+ // bytes will be either the version field (all_image_infos) or a Mach-O file magic constant.
+ // Version 13 and higher of dyld_all_image_infos is required to get the sharedCacheUUID field.
+
+ Error err;
+ uint32_t version_or_magic = process->ReadUnsignedIntegerFromMemory (all_image_infos, 4, -1, err);
+ if (version_or_magic != -1
+ && version_or_magic != HeaderMagic32
+ && version_or_magic != HeaderMagic32Swapped
+ && version_or_magic != HeaderMagic64
+ && version_or_magic != HeaderMagic64Swapped
+ && version_or_magic >= 13)
+ {
+ addr_t sharedCacheUUID_address = LLDB_INVALID_ADDRESS;
+ int wordsize = process->GetAddressByteSize();
+ if (wordsize == 8)
+ {
+ sharedCacheUUID_address = all_image_infos + 160; // sharedCacheUUID <mach-o/dyld_images.h>
+ }
+ if (wordsize == 4)
+ {
+ sharedCacheUUID_address = all_image_infos + 84; // sharedCacheUUID <mach-o/dyld_images.h>
+ }
+ if (sharedCacheUUID_address != LLDB_INVALID_ADDRESS)
+ {
+ uuid_t shared_cache_uuid;
+ if (process->ReadMemory (sharedCacheUUID_address, shared_cache_uuid, sizeof (uuid_t), err) == sizeof (uuid_t))
+ {
+ uuid.SetBytes (shared_cache_uuid);
+ }
+ }
+ }
+ }
+ return uuid;
+}
+
+UUID
+ObjectFileMachO::GetLLDBSharedCacheUUID ()
+{
+ UUID uuid;
+#if defined (__APPLE__) && defined (__arm__)
+ uint8_t *(*dyld_get_all_image_infos)(void);
+ dyld_get_all_image_infos = (uint8_t*(*)()) dlsym (RTLD_DEFAULT, "_dyld_get_all_image_infos");
+ if (dyld_get_all_image_infos)
+ {
+ uint8_t *dyld_all_image_infos_address = dyld_get_all_image_infos();
+ if (dyld_all_image_infos_address)
+ {
+ uint32_t version;
+ memcpy (&version, dyld_all_image_infos_address, 4);
+ if (version >= 13)
+ {
+ uint8_t *sharedCacheUUID_address = 0;
+ sharedCacheUUID_address = dyld_all_image_infos_address + 84; // sharedCacheUUID <mach-o/dyld_images.h>
+ uuid.SetBytes (sharedCacheUUID_address);
+ }
+ }
+ }
+#endif
+ return uuid;
+}
+
+
//------------------------------------------------------------------
// PluginInterface protocol
//------------------------------------------------------------------
Modified: lldb/branches/windows/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.h
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/windows/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.h?rev=179679&r1=179678&r2=179679&view=diff
==============================================================================
--- lldb/branches/windows/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.h (original)
+++ lldb/branches/windows/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.h Wed Apr 17 03:38:48 2013
@@ -43,10 +43,11 @@ public:
static lldb_private::ObjectFile *
CreateInstance (const lldb::ModuleSP &module_sp,
- lldb::DataBufferSP& dataSP,
+ lldb::DataBufferSP& data_sp,
+ lldb::offset_t data_offset,
const lldb_private::FileSpec* file,
- lldb::addr_t offset,
- lldb::addr_t length);
+ lldb::offset_t file_offset,
+ lldb::offset_t length);
static lldb_private::ObjectFile *
CreateMemoryInstance (const lldb::ModuleSP &module_sp,
@@ -55,7 +56,7 @@ public:
lldb::addr_t header_addr);
static bool
- MagicBytesMatch (lldb::DataBufferSP& dataSP,
+ MagicBytesMatch (lldb::DataBufferSP& data_sp,
lldb::addr_t offset,
lldb::addr_t length);
@@ -63,13 +64,14 @@ public:
// Member Functions
//------------------------------------------------------------------
ObjectFileMachO (const lldb::ModuleSP &module_sp,
- lldb::DataBufferSP& dataSP,
+ lldb::DataBufferSP& data_sp,
+ lldb::offset_t data_offset,
const lldb_private::FileSpec* file,
- lldb::addr_t offset,
- lldb::addr_t length);
+ lldb::offset_t offset,
+ lldb::offset_t length);
ObjectFileMachO (const lldb::ModuleSP &module_sp,
- lldb::DataBufferSP& dataSP,
+ lldb::DataBufferSP& data_sp,
const lldb::ProcessSP &process_sp,
lldb::addr_t header_addr);
@@ -85,7 +87,7 @@ public:
virtual bool
IsExecutable () const;
- virtual size_t
+ virtual uint32_t
GetAddressByteSize () const;
virtual lldb::AddressClass
@@ -143,9 +145,24 @@ public:
GetVersion (uint32_t *versions, uint32_t num_versions);
protected:
+
+ // Intended for same-host arm device debugging where lldb needs to
+ // detect libraries in the shared cache and augment the nlist entries
+ // with an on-disk dyld_shared_cache file. The process will record
+ // the shared cache UUID so the on-disk cache can be matched or rejected
+ // correctly.
+ lldb_private::UUID
+ GetProcessSharedCacheUUID (lldb_private::Process *);
+
+ // Intended for same-host arm device debugging where lldb will read
+ // shared cache libraries out of its own memory instead of the remote
+ // process' memory as an optimization. If lldb's shared cache UUID
+ // does not match the process' shared cache UUID, this optimization
+ // should not be used.
+ lldb_private::UUID
+ GetLLDBSharedCacheUUID ();
+
llvm::MachO::mach_header m_header;
- mutable std::auto_ptr<lldb_private::SectionList> m_sections_ap;
- mutable std::auto_ptr<lldb_private::Symtab> m_symtab_ap;
static const lldb_private::ConstString &GetSegmentNameTEXT();
static const lldb_private::ConstString &GetSegmentNameDATA();
static const lldb_private::ConstString &GetSegmentNameOBJC();
@@ -155,7 +172,7 @@ protected:
llvm::MachO::dysymtab_command m_dysymtab;
std::vector<llvm::MachO::segment_command_64> m_mach_segments;
std::vector<llvm::MachO::section_64> m_mach_sections;
- typedef lldb_private::RangeArray<uint32_t, uint32_t, 1> FileRangeArray;
+ typedef lldb_private::RangeVector<uint32_t, uint32_t> FileRangeArray;
lldb_private::Address m_entry_point_address;
FileRangeArray m_thread_context_offsets;
bool m_thread_context_offsets_valid;
Modified: lldb/branches/windows/source/Plugins/ObjectFile/PECOFF/ObjectFilePECOFF.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/windows/source/Plugins/ObjectFile/PECOFF/ObjectFilePECOFF.cpp?rev=179679&r1=179678&r2=179679&view=diff
==============================================================================
--- lldb/branches/windows/source/Plugins/ObjectFile/PECOFF/ObjectFilePECOFF.cpp (original)
+++ lldb/branches/windows/source/Plugins/ObjectFile/PECOFF/ObjectFilePECOFF.cpp Wed Apr 17 03:38:48 2013
@@ -148,11 +148,25 @@ ObjectFilePECOFF::GetPluginDescriptionSt
ObjectFile *
-ObjectFilePECOFF::CreateInstance (const lldb::ModuleSP &module_sp, DataBufferSP& dataSP, const FileSpec* file, addr_t offset, addr_t length)
+ObjectFilePECOFF::CreateInstance (const lldb::ModuleSP &module_sp,
+ DataBufferSP& data_sp,
+ lldb::offset_t data_offset,
+ const lldb_private::FileSpec* file,
+ lldb::offset_t file_offset,
+ lldb::offset_t length)
{
- if (ObjectFilePECOFF::MagicBytesMatch(dataSP))
+ if (!data_sp)
{
- std::auto_ptr<ObjectFile> objfile_ap(new ObjectFilePECOFF (module_sp, dataSP, file, offset, length));
+ data_sp = file->MemoryMapFileContents(file_offset, length);
+ data_offset = 0;
+ }
+
+ if (ObjectFilePECOFF::MagicBytesMatch(data_sp))
+ {
+ // Update the data to contain the entire file if it doesn't already
+ if (data_sp->GetByteSize() < length)
+ data_sp = file->MemoryMapFileContents(file_offset, length);
+ std::auto_ptr<ObjectFile> objfile_ap(new ObjectFilePECOFF (module_sp, data_sp, data_offset, file, file_offset, length));
if (objfile_ap.get() && objfile_ap->ParseHeader())
return objfile_ap.release();
}
@@ -169,21 +183,22 @@ ObjectFilePECOFF::CreateMemoryInstance (
}
bool
-ObjectFilePECOFF::MagicBytesMatch (DataBufferSP& dataSP)
+ObjectFilePECOFF::MagicBytesMatch (DataBufferSP& data_sp)
{
- DataExtractor data(dataSP, eByteOrderLittle, 4);
- uint32_t offset = 0;
+ DataExtractor data(data_sp, eByteOrderLittle, 4);
+ lldb::offset_t offset = 0;
uint16_t magic = data.GetU16 (&offset);
return magic == IMAGE_DOS_SIGNATURE;
}
ObjectFilePECOFF::ObjectFilePECOFF (const lldb::ModuleSP &module_sp,
- DataBufferSP& dataSP,
+ DataBufferSP& data_sp,
+ lldb::offset_t data_offset,
const FileSpec* file,
- addr_t offset,
- addr_t length) :
- ObjectFile (module_sp, file, offset, length, dataSP),
+ lldb::offset_t file_offset,
+ lldb::offset_t length) :
+ ObjectFile (module_sp, file, file_offset, length, data_sp, data_offset),
m_dos_header (),
m_coff_header (),
m_coff_header_opt (),
@@ -209,7 +224,7 @@ ObjectFilePECOFF::ParseHeader ()
lldb_private::Mutex::Locker locker(module_sp->GetMutex());
m_sect_headers.clear();
m_data.SetByteOrder (eByteOrderLittle);
- uint32_t offset = 0;
+ lldb::offset_t offset = 0;
if (ParseDOSHeader())
{
@@ -242,7 +257,7 @@ ObjectFilePECOFF::IsExecutable() const
return (m_coff_header.flags & IMAGE_FILE_DLL) == 0;
}
-size_t
+uint32_t
ObjectFilePECOFF::GetAddressByteSize () const
{
if (m_coff_header_opt.magic == OPT_HEADER_MAGIC_PE32_PLUS)
@@ -274,7 +289,7 @@ bool
ObjectFilePECOFF::ParseDOSHeader ()
{
bool success = false;
- uint32_t offset = 0;
+ lldb::offset_t offset = 0;
success = m_data.ValidOffsetForDataOfSize(0, sizeof(m_dos_header));
if (success)
@@ -329,7 +344,7 @@ ObjectFilePECOFF::ParseDOSHeader ()
// ParserCOFFHeader
//----------------------------------------------------------------------
bool
-ObjectFilePECOFF::ParseCOFFHeader(uint32_t* offset_ptr)
+ObjectFilePECOFF::ParseCOFFHeader(lldb::offset_t *offset_ptr)
{
bool success = m_data.ValidOffsetForDataOfSize (*offset_ptr, sizeof(m_coff_header));
if (success)
@@ -348,10 +363,10 @@ ObjectFilePECOFF::ParseCOFFHeader(uint32
}
bool
-ObjectFilePECOFF::ParseCOFFOptionalHeader(uint32_t* offset_ptr)
+ObjectFilePECOFF::ParseCOFFOptionalHeader(lldb::offset_t *offset_ptr)
{
bool success = false;
- const uint32_t end_offset = *offset_ptr + m_coff_header.hdrsize;
+ const lldb::offset_t end_offset = *offset_ptr + m_coff_header.hdrsize;
if (*offset_ptr < end_offset)
{
success = true;
@@ -432,7 +447,7 @@ ObjectFilePECOFF::ParseSectionHeaders (u
DataBufferSP section_header_data_sp(m_file.ReadFileContents (section_header_data_offset, section_header_byte_size));
DataExtractor section_header_data (section_header_data_sp, GetByteOrder(), addr_byte_size);
- uint32_t offset = 0;
+ lldb::offset_t offset = 0;
if (section_header_data.ValidOffsetForDataOfSize (offset, section_header_byte_size))
{
m_sect_headers.resize(nsects);
@@ -465,8 +480,8 @@ ObjectFilePECOFF::GetSectionName(std::st
{
if (sect.name[0] == '/')
{
- uint32_t stroff = strtoul(§.name[1], NULL, 10);
- uint32_t string_file_offset = m_coff_header.symoff + (m_coff_header.nsyms * 18) + stroff;
+ lldb::offset_t stroff = strtoul(§.name[1], NULL, 10);
+ lldb::offset_t string_file_offset = m_coff_header.symoff + (m_coff_header.nsyms * 18) + stroff;
const char *name = m_data.GetCStr (&string_file_offset);
if (name)
{
@@ -506,7 +521,7 @@ ObjectFilePECOFF::GetSymtab()
// Include the 4 bytes string table size at the end of the symbols
DataBufferSP symtab_data_sp(m_file.ReadFileContents (m_coff_header.symoff, symbol_data_size + 4));
DataExtractor symtab_data (symtab_data_sp, GetByteOrder(), addr_byte_size);
- uint32_t offset = symbol_data_size;
+ lldb::offset_t offset = symbol_data_size;
const uint32_t strtab_size = symtab_data.GetU32 (&offset);
DataBufferSP strtab_data_sp(m_file.ReadFileContents (m_coff_header.symoff + symbol_data_size + 4, strtab_size));
DataExtractor strtab_data (strtab_data_sp, GetByteOrder(), addr_byte_size);
Modified: lldb/branches/windows/source/Plugins/ObjectFile/PECOFF/ObjectFilePECOFF.h
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/windows/source/Plugins/ObjectFile/PECOFF/ObjectFilePECOFF.h?rev=179679&r1=179678&r2=179679&view=diff
==============================================================================
--- lldb/branches/windows/source/Plugins/ObjectFile/PECOFF/ObjectFilePECOFF.h (original)
+++ lldb/branches/windows/source/Plugins/ObjectFile/PECOFF/ObjectFilePECOFF.h Wed Apr 17 03:38:48 2013
@@ -36,10 +36,11 @@ public:
static ObjectFile *
CreateInstance (const lldb::ModuleSP &module_sp,
- lldb::DataBufferSP& dataSP,
+ lldb::DataBufferSP& data_sp,
+ lldb::offset_t data_offset,
const lldb_private::FileSpec* file,
- lldb::addr_t offset,
- lldb::addr_t length);
+ lldb::offset_t offset,
+ lldb::offset_t length);
static lldb_private::ObjectFile *
CreateMemoryInstance (const lldb::ModuleSP &module_sp,
@@ -47,14 +48,15 @@ public:
const lldb::ProcessSP &process_sp,
lldb::addr_t header_addr);
static bool
- MagicBytesMatch (lldb::DataBufferSP& dataSP);
+ MagicBytesMatch (lldb::DataBufferSP& data_sp);
ObjectFilePECOFF (const lldb::ModuleSP &module_sp,
- lldb::DataBufferSP& dataSP,
+ lldb::DataBufferSP& data_sp,
+ lldb::offset_t data_offset,
const lldb_private::FileSpec* file,
- lldb::addr_t offset,
- lldb::addr_t length);
+ lldb::offset_t file_offset,
+ lldb::offset_t length);
virtual
~ObjectFilePECOFF();
@@ -68,7 +70,7 @@ public:
virtual bool
IsExecutable () const;
- virtual size_t
+ virtual uint32_t
GetAddressByteSize () const;
// virtual lldb_private::AddressClass
@@ -212,8 +214,8 @@ protected:
} coff_symbol_t;
bool ParseDOSHeader ();
- bool ParseCOFFHeader (uint32_t* offset_ptr);
- bool ParseCOFFOptionalHeader (uint32_t* offset_ptr);
+ bool ParseCOFFHeader (lldb::offset_t *offset_ptr);
+ bool ParseCOFFOptionalHeader (lldb::offset_t *offset_ptr);
bool ParseSectionHeaders (uint32_t offset);
static void DumpDOSHeader(lldb_private::Stream *s, const dos_header_t& header);
@@ -227,8 +229,6 @@ protected:
typedef SectionHeaderColl::iterator SectionHeaderCollIter;
typedef SectionHeaderColl::const_iterator SectionHeaderCollConstIter;
private:
- mutable std::auto_ptr<lldb_private::SectionList> m_sections_ap;
- mutable std::auto_ptr<lldb_private::Symtab> m_symtab_ap;
dos_header_t m_dos_header;
coff_header_t m_coff_header;
coff_opt_header_t m_coff_header_opt;
Modified: lldb/branches/windows/source/Plugins/OperatingSystem/CMakeLists.txt
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/windows/source/Plugins/OperatingSystem/CMakeLists.txt?rev=179679&r1=179678&r2=179679&view=diff
==============================================================================
--- lldb/branches/windows/source/Plugins/OperatingSystem/CMakeLists.txt (original)
+++ lldb/branches/windows/source/Plugins/OperatingSystem/CMakeLists.txt Wed Apr 17 03:38:48 2013
@@ -1 +1,2 @@
#add_subdirectory(Darwin-Kernel)
+add_subdirectory(Python)
Modified: lldb/branches/windows/source/Plugins/OperatingSystem/Python/OperatingSystemPython.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/windows/source/Plugins/OperatingSystem/Python/OperatingSystemPython.cpp?rev=179679&r1=179678&r2=179679&view=diff
==============================================================================
--- lldb/branches/windows/source/Plugins/OperatingSystem/Python/OperatingSystemPython.cpp (original)
+++ lldb/branches/windows/source/Plugins/OperatingSystem/Python/OperatingSystemPython.cpp Wed Apr 17 03:38:48 2013
@@ -20,7 +20,6 @@
#include "lldb/Core/Debugger.h"
#include "lldb/Core/Module.h"
#include "lldb/Core/PluginManager.h"
-#include "lldb/Interpreter/PythonDataObjects.h"
#include "lldb/Core/RegisterValue.h"
#include "lldb/Core/ValueObjectVariable.h"
#include "lldb/Interpreter/CommandInterpreter.h"
@@ -87,11 +86,11 @@ OperatingSystemPython::OperatingSystemPy
m_thread_list_valobj_sp (),
m_register_info_ap (),
m_interpreter (NULL),
- m_python_object (NULL)
+ m_python_object_sp ()
{
if (!process)
return;
- lldb::TargetSP target_sp = process->CalculateTarget();
+ TargetSP target_sp = process->CalculateTarget();
if (!target_sp)
return;
m_interpreter = target_sp->GetDebugger().GetCommandInterpreter().GetScriptInterpreter();
@@ -114,9 +113,9 @@ OperatingSystemPython::OperatingSystemPy
os_plugin_class_name.erase (py_extension_pos);
// Add ".OperatingSystemPlugIn" to the module name to get a string like "modulename.OperatingSystemPlugIn"
os_plugin_class_name += ".OperatingSystemPlugIn";
- auto object_sp = m_interpreter->CreateOSPlugin(os_plugin_class_name.c_str(), process->CalculateProcess());
- if (object_sp)
- m_python_object = object_sp->GetObject();
+ ScriptInterpreterObjectSP object_sp = m_interpreter->OSPlugin_CreatePluginObject(os_plugin_class_name.c_str(), process->CalculateProcess());
+ if (object_sp && object_sp->GetObject())
+ m_python_object_sp = object_sp;
}
}
}
@@ -131,18 +130,14 @@ OperatingSystemPython::GetDynamicRegiste
{
if (m_register_info_ap.get() == NULL)
{
- if (!m_interpreter || !m_python_object)
+ if (!m_interpreter || !m_python_object_sp)
return NULL;
- LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_PROCESS));
+ Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_PROCESS));
if (log)
log->Printf ("OperatingSystemPython::GetDynamicRegisterInfo() fetching thread register definitions from python for pid %" PRIu64, m_process->GetID());
- auto object_sp = m_interpreter->OSPlugin_QueryForRegisterInfo(m_interpreter->MakeScriptObject(m_python_object));
- if (!object_sp)
- return NULL;
- PythonDataObject dictionary_data_obj((PyObject*)object_sp->GetObject());
- PythonDataDictionary dictionary = dictionary_data_obj.GetDictionaryObject();
+ PythonDictionary dictionary(m_interpreter->OSPlugin_RegisterInfo(m_python_object_sp));
if (!dictionary)
return NULL;
@@ -177,10 +172,10 @@ OperatingSystemPython::GetPluginVersion(
bool
OperatingSystemPython::UpdateThreadList (ThreadList &old_thread_list, ThreadList &new_thread_list)
{
- if (!m_interpreter || !m_python_object)
+ if (!m_interpreter || !m_python_object_sp)
return false;
- LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_PROCESS));
+ Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_PROCESS));
// First thing we have to do is get the API lock, and the run lock. We're going to change the thread
// content of the process, and we're going to use python, which requires the API lock to do it.
@@ -191,50 +186,42 @@ OperatingSystemPython::UpdateThreadList
if (log)
log->Printf ("OperatingSystemPython::UpdateThreadList() fetching thread data from python for pid %" PRIu64, m_process->GetID());
- auto object_sp = m_interpreter->OSPlugin_QueryForThreadsInfo(m_interpreter->MakeScriptObject(m_python_object));
- if (!object_sp)
- return false;
- PythonDataObject pyobj((PyObject*)object_sp->GetObject());
- PythonDataArray threads_array (pyobj.GetArrayObject());
- if (threads_array)
+ // The threads that are in "new_thread_list" upon entry are the threads from the
+ // lldb_private::Process subclass, no memory threads will be in this list.
+
+ auto lock = m_interpreter->AcquireInterpreterLock(); // to make sure threads_list stays alive
+ PythonList threads_list(m_interpreter->OSPlugin_ThreadsInfo(m_python_object_sp));
+ if (threads_list)
{
-// const uint32_t num_old_threads = old_thread_list.GetSize(false);
-// for (uint32_t i=0; i<num_old_threads; ++i)
-// {
-// ThreadSP old_thread_sp(old_thread_list.GetThreadAtIndex(i, false));
-// if (old_thread_sp->GetID() < 0x10000)
-// new_thread_list.AddThread (old_thread_sp);
-// }
-
- PythonDataString tid_pystr("tid");
- PythonDataString name_pystr("name");
- PythonDataString queue_pystr("queue");
- PythonDataString state_pystr("state");
- PythonDataString stop_reason_pystr("stop_reason");
- PythonDataString reg_data_addr_pystr ("register_data_addr");
-
- const uint32_t num_threads = threads_array.GetSize();
- for (uint32_t i=0; i<num_threads; ++i)
+ ThreadList core_thread_list(new_thread_list);
+
+ threads_list.Dump(); // REMOVE THIS
+
+ uint32_t i;
+ const uint32_t num_threads = threads_list.GetSize();
+ for (i=0; i<num_threads; ++i)
{
- PythonDataDictionary thread_dict(threads_array.GetItemAtIndex(i).GetDictionaryObject());
+ PythonDictionary thread_dict(threads_list.GetItemAtIndex(i));
if (thread_dict)
{
- const tid_t tid = thread_dict.GetItemForKeyAsInteger (tid_pystr, LLDB_INVALID_THREAD_ID);
- const addr_t reg_data_addr = thread_dict.GetItemForKeyAsInteger (reg_data_addr_pystr, LLDB_INVALID_ADDRESS);
- const char *name = thread_dict.GetItemForKeyAsString (name_pystr);
- const char *queue = thread_dict.GetItemForKeyAsString (queue_pystr);
- //const char *state = thread_dict.GetItemForKeyAsString (state_pystr);
- //const char *stop_reason = thread_dict.GetItemForKeyAsString (stop_reason_pystr);
-
- ThreadSP thread_sp (old_thread_list.FindThreadByID (tid, false));
- if (!thread_sp)
- thread_sp.reset (new ThreadMemory (*m_process,
- tid,
- name,
- queue,
- reg_data_addr));
- new_thread_list.AddThread(thread_sp);
-
+ if (thread_dict.GetItemForKey("core"))
+ {
+ // We have some threads that are saying they are on a "core", which means
+ // they map the threads that are gotten from the lldb_private::Process subclass
+ // so clear the new threads list so the core threads don't show up
+ new_thread_list.Clear();
+ break;
+ }
+ }
+ }
+ for (i=0; i<num_threads; ++i)
+ {
+ PythonDictionary thread_dict(threads_list.GetItemAtIndex(i));
+ if (thread_dict)
+ {
+ ThreadSP thread_sp (CreateThreadFromThreadInfo (thread_dict, core_thread_list, old_thread_list, NULL));
+ if (thread_sp)
+ new_thread_list.AddThread(thread_sp);
}
}
}
@@ -245,16 +232,67 @@ OperatingSystemPython::UpdateThreadList
return new_thread_list.GetSize(false) > 0;
}
+ThreadSP
+OperatingSystemPython::CreateThreadFromThreadInfo (PythonDictionary &thread_dict,
+ ThreadList &core_thread_list,
+ ThreadList &old_thread_list,
+ bool *did_create_ptr)
+{
+ ThreadSP thread_sp;
+ if (thread_dict)
+ {
+ PythonString tid_pystr("tid");
+ const tid_t tid = thread_dict.GetItemForKeyAsInteger (tid_pystr, LLDB_INVALID_THREAD_ID);
+ if (tid != LLDB_INVALID_THREAD_ID)
+ {
+ PythonString core_pystr("core");
+ PythonString name_pystr("name");
+ PythonString queue_pystr("queue");
+ PythonString state_pystr("state");
+ PythonString stop_reason_pystr("stop_reason");
+ PythonString reg_data_addr_pystr ("register_data_addr");
+
+ const uint32_t core_number = thread_dict.GetItemForKeyAsInteger (core_pystr, UINT32_MAX);
+ const addr_t reg_data_addr = thread_dict.GetItemForKeyAsInteger (reg_data_addr_pystr, LLDB_INVALID_ADDRESS);
+ const char *name = thread_dict.GetItemForKeyAsString (name_pystr);
+ const char *queue = thread_dict.GetItemForKeyAsString (queue_pystr);
+ //const char *state = thread_dict.GetItemForKeyAsString (state_pystr);
+ //const char *stop_reason = thread_dict.GetItemForKeyAsString (stop_reason_pystr);
+
+ thread_sp = old_thread_list.FindThreadByID (tid, false);
+ if (!thread_sp)
+ {
+ if (did_create_ptr)
+ *did_create_ptr = true;
+ thread_sp.reset (new ThreadMemory (*m_process,
+ tid,
+ name,
+ queue,
+ reg_data_addr));
+
+ }
+
+ if (core_number < core_thread_list.GetSize(false))
+ {
+ thread_sp->SetBackingThread(core_thread_list.GetThreadAtIndex(core_number, false));
+ }
+ }
+ }
+ return thread_sp;
+}
+
+
+
void
OperatingSystemPython::ThreadWasSelected (Thread *thread)
{
}
RegisterContextSP
-OperatingSystemPython::CreateRegisterContextForThread (Thread *thread, lldb::addr_t reg_data_addr)
+OperatingSystemPython::CreateRegisterContextForThread (Thread *thread, addr_t reg_data_addr)
{
RegisterContextSP reg_ctx_sp;
- if (!m_interpreter || !m_python_object || !thread)
+ if (!m_interpreter || !m_python_object_sp || !thread)
return RegisterContextSP();
// First thing we have to do is get the API lock, and the run lock. We're going to change the thread
@@ -263,8 +301,9 @@ OperatingSystemPython::CreateRegisterCon
Target &target = m_process->GetTarget();
Mutex::Locker api_locker (target.GetAPIMutex());
- LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_THREAD));
+ Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_THREAD));
+ auto lock = m_interpreter->AcquireInterpreterLock(); // to make sure python objects stays alive
if (reg_data_addr != LLDB_INVALID_ADDRESS)
{
// The registers data is in contiguous memory, just create the register
@@ -280,13 +319,7 @@ OperatingSystemPython::CreateRegisterCon
if (log)
log->Printf ("OperatingSystemPython::CreateRegisterContextForThread (tid = 0x%" PRIx64 ") fetching register data from python", thread->GetID());
- auto object_sp = m_interpreter->OSPlugin_QueryForRegisterContextData (m_interpreter->MakeScriptObject(m_python_object),
- thread->GetID());
-
- if (!object_sp)
- return RegisterContextSP();
-
- PythonDataString reg_context_data((PyObject*)object_sp->GetObject());
+ PythonString reg_context_data(m_interpreter->OSPlugin_RegisterContextData (m_python_object_sp, thread->GetID()));
if (reg_context_data)
{
DataBufferSP data_sp (new DataBufferHeap (reg_context_data.GetString(),
@@ -315,5 +348,38 @@ OperatingSystemPython::CreateThreadStopR
return stop_info_sp;
}
+lldb::ThreadSP
+OperatingSystemPython::CreateThread (lldb::tid_t tid, addr_t context)
+{
+ Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_THREAD));
+
+ if (log)
+ log->Printf ("OperatingSystemPython::CreateThread (tid = 0x%" PRIx64 ", context = 0x%" PRIx64 ") fetching register data from python", tid, context);
+
+ if (m_interpreter && m_python_object_sp)
+ {
+ // First thing we have to do is get the API lock, and the run lock. We're going to change the thread
+ // content of the process, and we're going to use python, which requires the API lock to do it.
+ // So get & hold that. This is a recursive lock so we can grant it to any Python code called on the stack below us.
+ Target &target = m_process->GetTarget();
+ Mutex::Locker api_locker (target.GetAPIMutex());
+
+ auto lock = m_interpreter->AcquireInterpreterLock(); // to make sure thread_info_dict stays alive
+ PythonDictionary thread_info_dict (m_interpreter->OSPlugin_CreateThread(m_python_object_sp, tid, context));
+ if (thread_info_dict)
+ {
+ ThreadList core_threads(m_process);
+ ThreadList &thread_list = m_process->GetThreadList();
+ bool did_create = false;
+ ThreadSP thread_sp (CreateThreadFromThreadInfo (thread_info_dict, core_threads, thread_list, &did_create));
+ if (did_create)
+ thread_list.AddThread(thread_sp);
+ return thread_sp;
+ }
+ }
+ return ThreadSP();
+}
+
+
#endif // #ifndef LLDB_DISABLE_PYTHON
Modified: lldb/branches/windows/source/Plugins/OperatingSystem/Python/OperatingSystemPython.h
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/windows/source/Plugins/OperatingSystem/Python/OperatingSystemPython.h?rev=179679&r1=179678&r2=179679&view=diff
==============================================================================
--- lldb/branches/windows/source/Plugins/OperatingSystem/Python/OperatingSystemPython.h (original)
+++ lldb/branches/windows/source/Plugins/OperatingSystem/Python/OperatingSystemPython.h Wed Apr 17 03:38:48 2013
@@ -78,19 +78,32 @@ public:
virtual lldb::StopInfoSP
CreateThreadStopReason (lldb_private::Thread *thread);
+ //------------------------------------------------------------------
+ // Method for lazy creation of threads on demand
+ //------------------------------------------------------------------
+ virtual lldb::ThreadSP
+ CreateThread (lldb::tid_t tid, lldb::addr_t context);
+
protected:
bool IsValid() const
{
- return m_python_object != NULL;
+ return m_python_object_sp && m_python_object_sp->GetObject() != NULL;
}
+
+ lldb::ThreadSP
+ CreateThreadFromThreadInfo (lldb_private::PythonDictionary &thread_dict,
+ lldb_private::ThreadList &core_thread_list,
+ lldb_private::ThreadList &old_thread_list,
+ bool *did_create_ptr);
+
DynamicRegisterInfo *
GetDynamicRegisterInfo ();
lldb::ValueObjectSP m_thread_list_valobj_sp;
std::auto_ptr<DynamicRegisterInfo> m_register_info_ap;
lldb_private::ScriptInterpreter *m_interpreter;
- void* m_python_object;
+ lldb::ScriptInterpreterObjectSP m_python_object_sp;
};
Modified: lldb/branches/windows/source/Plugins/Platform/CMakeLists.txt
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/windows/source/Plugins/Platform/CMakeLists.txt?rev=179679&r1=179678&r2=179679&view=diff
==============================================================================
--- lldb/branches/windows/source/Plugins/Platform/CMakeLists.txt (original)
+++ lldb/branches/windows/source/Plugins/Platform/CMakeLists.txt Wed Apr 17 03:38:48 2013
@@ -1,5 +1,5 @@
-#add_subdirectory(FreeBSD)
+add_subdirectory(FreeBSD)
add_subdirectory(gdb-server)
-#add_subdirectory(Linux)
+add_subdirectory(Linux)
add_subdirectory(MacOSX)
add_subdirectory(Windows)
Modified: lldb/branches/windows/source/Plugins/Platform/FreeBSD/PlatformFreeBSD.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/windows/source/Plugins/Platform/FreeBSD/PlatformFreeBSD.cpp?rev=179679&r1=179678&r2=179679&view=diff
==============================================================================
--- lldb/branches/windows/source/Plugins/Platform/FreeBSD/PlatformFreeBSD.cpp (original)
+++ lldb/branches/windows/source/Plugins/Platform/FreeBSD/PlatformFreeBSD.cpp Wed Apr 17 03:38:48 2013
@@ -13,7 +13,9 @@
// C Includes
#include <stdio.h>
+#ifdef _POSIX_SOURCE
#include <sys/utsname.h>
+#endif
// C++ Includes
// Other libraries and framework includes
@@ -645,6 +647,10 @@ PlatformFreeBSD::GetSupportedArchitectur
void
PlatformFreeBSD::GetStatus (Stream &strm)
{
+#ifdef _WIN32
+ strm << "Windows";
+ return;
+#else
struct utsname un;
if (uname(&un)) {
@@ -654,4 +660,5 @@ PlatformFreeBSD::GetStatus (Stream &strm
strm << "Host: " << un.sysname << ' ' << un.release << ' ' << un.version << '\n';
Platform::GetStatus(strm);
+#endif
}
Modified: lldb/branches/windows/source/Plugins/Platform/Linux/PlatformLinux.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/windows/source/Plugins/Platform/Linux/PlatformLinux.cpp?rev=179679&r1=179678&r2=179679&view=diff
==============================================================================
--- lldb/branches/windows/source/Plugins/Platform/Linux/PlatformLinux.cpp (original)
+++ lldb/branches/windows/source/Plugins/Platform/Linux/PlatformLinux.cpp Wed Apr 17 03:38:48 2013
@@ -13,7 +13,9 @@
// C Includes
#include <stdio.h>
+#ifndef _WIN32
#include <sys/utsname.h>
+#endif
// C++ Includes
// Other libraries and framework includes
@@ -331,7 +333,10 @@ PlatformLinux::GetSupportedArchitectureA
void
PlatformLinux::GetStatus (Stream &strm)
{
- struct utsname un;
+#ifdef _WIN32
+ strm << "Windows";
+#else
+ struct utsname un;
if (uname(&un)) {
strm << "Linux";
@@ -339,6 +344,7 @@ PlatformLinux::GetStatus (Stream &strm)
}
strm << un.sysname << ' ' << un.release << ' ' << un.version << '\n';
+#endif
}
size_t
Modified: lldb/branches/windows/source/Plugins/Platform/MacOSX/CMakeLists.txt
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/windows/source/Plugins/Platform/MacOSX/CMakeLists.txt?rev=179679&r1=179678&r2=179679&view=diff
==============================================================================
--- lldb/branches/windows/source/Plugins/Platform/MacOSX/CMakeLists.txt (original)
+++ lldb/branches/windows/source/Plugins/Platform/MacOSX/CMakeLists.txt Wed Apr 17 03:38:48 2013
@@ -2,6 +2,7 @@ set(LLVM_NO_RTTI 1)
add_lldb_library(lldbPluginPlatformMacOSX
PlatformDarwin.cpp
+ PlatformDarwinKernel.cpp
PlatformiOSSimulator.cpp
PlatformMacOSX.cpp
PlatformRemoteiOS.cpp
Modified: lldb/branches/windows/source/Plugins/Platform/MacOSX/PlatformDarwin.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/windows/source/Plugins/Platform/MacOSX/PlatformDarwin.cpp?rev=179679&r1=179678&r2=179679&view=diff
==============================================================================
--- lldb/branches/windows/source/Plugins/Platform/MacOSX/PlatformDarwin.cpp (original)
+++ lldb/branches/windows/source/Plugins/Platform/MacOSX/PlatformDarwin.cpp Wed Apr 17 03:38:48 2013
@@ -24,6 +24,8 @@
#include "lldb/Host/Host.h"
#include "lldb/Host/Symbols.h"
#include "lldb/Symbol/ObjectFile.h"
+#include "lldb/Symbol/SymbolFile.h"
+#include "lldb/Symbol/SymbolVendor.h"
#include "lldb/Target/Target.h"
using namespace lldb;
@@ -50,87 +52,74 @@ PlatformDarwin::~PlatformDarwin()
{
}
-FileSpec
-PlatformDarwin::LocateExecutableScriptingResource (const ModuleSpec &module_spec)
-{
- const FileSpec *exec_fspec = module_spec.GetFileSpecPtr();
- // APIs such as NSLinkModule() allow us to attach a library without a filename
- // make sure we do not crash under those circumstances
- if (!exec_fspec)
- return FileSpec();
-
- // if the arch and uuid are ever used for anything other than display purposes
- // make sure they are not NULL before proceeding
- const ArchSpec *arch = module_spec.GetArchitecturePtr();
- const UUID *uuid = module_spec.GetUUIDPtr();
-
- const char* module_directory = exec_fspec->GetDirectory().GetCString();
-
- // NB some extensions might be meaningful and should not be stripped - "this.binary.file"
- // should not lose ".file" but GetFileNameStrippingExtension() will do precisely that.
- // Ideally, we should have a per-platform list of extensions (".exe", ".app", ".dSYM", ".framework")
- // which should be stripped while leaving "this.binary.file" as-is.
- const char* module_basename = exec_fspec->GetFileNameStrippingExtension().GetCString();
-
- if (!module_directory || !module_basename)
- return FileSpec();
-
- Timer scoped_timer (__PRETTY_FUNCTION__,
- "LocateExecutableScriptingResource (file = %s, arch = %s, uuid = %p)",
- exec_fspec ? exec_fspec->GetFilename().AsCString ("<NULL>") : "<NULL>",
- arch ? arch->GetArchitectureName() : "<NULL>",
- uuid);
-
- // FIXME: for Python, we cannot allow dots in the middle of the filenames we import.
- // Theoretically, different scripting languages may have different sets of
- // forbidden tokens in filenames, and that should be dealt with by each ScriptInterpreter.
- // For now, we just replace dots with underscores, but if we ever support anything
- // other than Python we will need to rework this
- std::auto_ptr<char> module_basename_fixed_ap(new char[strlen(module_basename)+1]);
- char* module_basename_fixed = module_basename_fixed_ap.get();
- strcpy(module_basename_fixed, module_basename);
- while (*module_basename_fixed)
- {
- if (*module_basename_fixed == '.')
- *module_basename_fixed = '_';
- module_basename_fixed++;
- }
- module_basename_fixed = module_basename_fixed_ap.get();
-
- FileSpec symbol_fspec (Symbols::LocateExecutableSymbolFile(module_spec));
-
- FileSpec script_fspec;
-
- StreamString path_string;
-
- if (symbol_fspec && symbol_fspec.Exists())
- {
- // for OSX we are going to be in .dSYM/Contents/Resources/DWARF/<basename>
- // let us go to .dSYM/Contents/Resources/Python/<basename>.py and see if the file exists
- path_string.Printf("%s/../Python/%s.py",symbol_fspec.GetDirectory().AsCString(""),module_basename_fixed);
- script_fspec.SetFile(path_string.GetData(), true);
- if (!script_fspec.Exists())
- script_fspec.Clear();
- }
-
- // no symbols or symbols did not have a scripting resource
- if (!symbol_fspec || !script_fspec)
- {
- path_string.Clear();
- path_string.Printf("%s.framework",module_basename);
- if (module_directory && strstr(module_directory, path_string.GetData()))
+FileSpecList
+PlatformDarwin::LocateExecutableScriptingResources (Target *target,
+ Module &module)
+{
+ FileSpecList file_list;
+ if (target && target->GetDebugger().GetScriptLanguage() == eScriptLanguagePython)
+ {
+ // NB some extensions might be meaningful and should not be stripped - "this.binary.file"
+ // should not lose ".file" but GetFileNameStrippingExtension() will do precisely that.
+ // Ideally, we should have a per-platform list of extensions (".exe", ".app", ".dSYM", ".framework")
+ // which should be stripped while leaving "this.binary.file" as-is.
+ FileSpec module_spec = module.GetFileSpec();
+
+ if (module_spec)
{
- // we are going to be in foo.framework/Versions/X/foo
- path_string.Clear();
- // let's go to foo.framework/Versions/X/Resources/Python/foo.py
- path_string.Printf("%s/Resources/Python/%s.py",module_directory,module_basename_fixed);
- script_fspec.SetFile(path_string.GetData(), true);
- if (!script_fspec.Exists())
- script_fspec.Clear();
+ SymbolVendor *symbols = module.GetSymbolVendor ();
+ if (symbols)
+ {
+ SymbolFile *symfile = symbols->GetSymbolFile();
+ if (symfile)
+ {
+ ObjectFile *objfile = symfile->GetObjectFile();
+ if (objfile)
+ {
+ FileSpec symfile_spec (objfile->GetFileSpec());
+ if (symfile_spec && symfile_spec.Exists())
+ {
+ while (module_spec.GetFilename())
+ {
+ std::string module_basename (module_spec.GetFilename().GetCString());
+
+ // FIXME: for Python, we cannot allow certain characters in module
+ // filenames we import. Theoretically, different scripting languages may
+ // have different sets of forbidden tokens in filenames, and that should
+ // be dealt with by each ScriptInterpreter. For now, we just replace dots
+ // with underscores, but if we ever support anything other than Python
+ // we will need to rework this
+ std::replace(module_basename.begin(), module_basename.end(), '.', '_');
+ std::replace(module_basename.begin(), module_basename.end(), ' ', '_');
+ std::replace(module_basename.begin(), module_basename.end(), '-', '_');
+
+
+ StreamString path_string;
+ // for OSX we are going to be in .dSYM/Contents/Resources/DWARF/<basename>
+ // let us go to .dSYM/Contents/Resources/Python/<basename>.py and see if the file exists
+ path_string.Printf("%s/../Python/%s.py",symfile_spec.GetDirectory().GetCString(), module_basename.c_str());
+ FileSpec script_fspec(path_string.GetData(), true);
+ if (script_fspec.Exists())
+ {
+ file_list.Append (script_fspec);
+ break;
+ }
+
+ // If we didn't find the python file, then keep
+ // stripping the extensions and try again
+ ConstString filename_no_extension (module_spec.GetFileNameStrippingExtension());
+ if (module_spec.GetFilename() == filename_no_extension)
+ break;
+
+ module_spec.GetFilename() = filename_no_extension;
+ }
+ }
+ }
+ }
+ }
}
}
-
- return script_fspec;
+ return file_list;
}
Error
@@ -326,33 +315,52 @@ PlatformDarwin::GetSharedModule (const M
FileSpec bundle_directory;
if (Host::GetBundleDirectory (platform_file, bundle_directory))
{
- char platform_path[PATH_MAX];
- char bundle_dir[PATH_MAX];
- platform_file.GetPath (platform_path, sizeof(platform_path));
- const size_t bundle_directory_len = bundle_directory.GetPath (bundle_dir, sizeof(bundle_dir));
- char new_path[PATH_MAX];
- size_t num_module_search_paths = module_search_paths_ptr->GetSize();
- for (size_t i=0; i<num_module_search_paths; ++i)
+ if (platform_file == bundle_directory)
{
- const size_t search_path_len = module_search_paths_ptr->GetFileSpecAtIndex(i).GetPath(new_path, sizeof(new_path));
- if (search_path_len < sizeof(new_path))
+ ModuleSpec new_module_spec (module_spec);
+ new_module_spec.GetFileSpec() = bundle_directory;
+ if (Host::ResolveExecutableInBundle (new_module_spec.GetFileSpec()))
{
- snprintf (new_path + search_path_len, sizeof(new_path) - search_path_len, "/%s", platform_path + bundle_directory_len);
- FileSpec new_file_spec (new_path, false);
- if (new_file_spec.Exists())
+ Error new_error (Platform::GetSharedModule (new_module_spec,
+ module_sp,
+ NULL,
+ old_module_sp_ptr,
+ did_create_ptr));
+
+ if (module_sp)
+ return new_error;
+ }
+ }
+ else
+ {
+ char platform_path[PATH_MAX];
+ char bundle_dir[PATH_MAX];
+ platform_file.GetPath (platform_path, sizeof(platform_path));
+ const size_t bundle_directory_len = bundle_directory.GetPath (bundle_dir, sizeof(bundle_dir));
+ char new_path[PATH_MAX];
+ size_t num_module_search_paths = module_search_paths_ptr->GetSize();
+ for (size_t i=0; i<num_module_search_paths; ++i)
+ {
+ const size_t search_path_len = module_search_paths_ptr->GetFileSpecAtIndex(i).GetPath(new_path, sizeof(new_path));
+ if (search_path_len < sizeof(new_path))
{
- ModuleSpec new_module_spec (module_spec);
- new_module_spec.GetFileSpec() = new_file_spec;
- Error new_error (Platform::GetSharedModule (new_module_spec,
- module_sp,
- NULL,
- old_module_sp_ptr,
- did_create_ptr));
-
- if (module_sp)
+ snprintf (new_path + search_path_len, sizeof(new_path) - search_path_len, "/%s", platform_path + bundle_directory_len);
+ FileSpec new_file_spec (new_path, false);
+ if (new_file_spec.Exists())
{
- module_sp->SetPlatformFileSpec(new_file_spec);
- return new_error;
+ ModuleSpec new_module_spec (module_spec);
+ new_module_spec.GetFileSpec() = new_file_spec;
+ Error new_error (Platform::GetSharedModule (new_module_spec,
+ module_sp,
+ NULL,
+ old_module_sp_ptr,
+ did_create_ptr));
+
+ if (module_sp)
+ {
+ module_sp->SetPlatformFileSpec(new_file_spec);
+ return new_error;
+ }
}
}
}
@@ -734,18 +742,22 @@ PlatformDarwin::ARMGetSupportedArchitect
case 1: arch.SetTriple ("armv7f-apple-ios"); return true;
case 2: arch.SetTriple ("armv7k-apple-ios"); return true;
case 3: arch.SetTriple ("armv7s-apple-ios"); return true;
- case 4: arch.SetTriple ("armv6-apple-ios"); return true;
- case 5: arch.SetTriple ("armv5-apple-ios"); return true;
- case 6: arch.SetTriple ("armv4-apple-ios"); return true;
- case 7: arch.SetTriple ("arm-apple-ios"); return true;
- case 8: arch.SetTriple ("thumbv7-apple-ios"); return true;
- case 9: arch.SetTriple ("thumbv7f-apple-ios"); return true;
- case 10: arch.SetTriple ("thumbv7k-apple-ios"); return true;
- case 11: arch.SetTriple ("thumbv7s-apple-ios"); return true;
- case 12: arch.SetTriple ("thumbv6-apple-ios"); return true;
- case 13: arch.SetTriple ("thumbv5-apple-ios"); return true;
- case 14: arch.SetTriple ("thumbv4t-apple-ios"); return true;
- case 15: arch.SetTriple ("thumb-apple-ios"); return true;
+ case 4: arch.SetTriple ("armv7m-apple-ios"); return true;
+ case 5: arch.SetTriple ("armv7em-apple-ios"); return true;
+ case 6: arch.SetTriple ("armv6-apple-ios"); return true;
+ case 7: arch.SetTriple ("armv5-apple-ios"); return true;
+ case 8: arch.SetTriple ("armv4-apple-ios"); return true;
+ case 9: arch.SetTriple ("arm-apple-ios"); return true;
+ case 10: arch.SetTriple ("thumbv7-apple-ios"); return true;
+ case 11: arch.SetTriple ("thumbv7f-apple-ios"); return true;
+ case 12: arch.SetTriple ("thumbv7k-apple-ios"); return true;
+ case 13: arch.SetTriple ("thumbv7s-apple-ios"); return true;
+ case 14: arch.SetTriple ("thumbv7m-apple-ios"); return true;
+ case 15: arch.SetTriple ("thumbv7em-apple-ios"); return true;
+ case 16: arch.SetTriple ("thumbv6-apple-ios"); return true;
+ case 17: arch.SetTriple ("thumbv5-apple-ios"); return true;
+ case 18: arch.SetTriple ("thumbv4t-apple-ios"); return true;
+ case 19: arch.SetTriple ("thumb-apple-ios"); return true;
default: break;
}
break;
@@ -807,6 +819,44 @@ PlatformDarwin::ARMGetSupportedArchitect
}
break;
+ case ArchSpec::eCore_arm_armv7m:
+ switch (idx)
+ {
+ case 0: arch.SetTriple ("armv7m-apple-ios"); return true;
+ case 1: arch.SetTriple ("armv7-apple-ios"); return true;
+ case 2: arch.SetTriple ("armv6-apple-ios"); return true;
+ case 3: arch.SetTriple ("armv5-apple-ios"); return true;
+ case 4: arch.SetTriple ("armv4-apple-ios"); return true;
+ case 5: arch.SetTriple ("arm-apple-ios"); return true;
+ case 6: arch.SetTriple ("thumbv7m-apple-ios"); return true;
+ case 7: arch.SetTriple ("thumbv7-apple-ios"); return true;
+ case 8: arch.SetTriple ("thumbv6-apple-ios"); return true;
+ case 9: arch.SetTriple ("thumbv5-apple-ios"); return true;
+ case 10: arch.SetTriple ("thumbv4t-apple-ios"); return true;
+ case 11: arch.SetTriple ("thumb-apple-ios"); return true;
+ default: break;
+ }
+ break;
+
+ case ArchSpec::eCore_arm_armv7em:
+ switch (idx)
+ {
+ case 0: arch.SetTriple ("armv7em-apple-ios"); return true;
+ case 1: arch.SetTriple ("armv7-apple-ios"); return true;
+ case 2: arch.SetTriple ("armv6-apple-ios"); return true;
+ case 3: arch.SetTriple ("armv5-apple-ios"); return true;
+ case 4: arch.SetTriple ("armv4-apple-ios"); return true;
+ case 5: arch.SetTriple ("arm-apple-ios"); return true;
+ case 6: arch.SetTriple ("thumbv7em-apple-ios"); return true;
+ case 7: arch.SetTriple ("thumbv7-apple-ios"); return true;
+ case 8: arch.SetTriple ("thumbv6-apple-ios"); return true;
+ case 9: arch.SetTriple ("thumbv5-apple-ios"); return true;
+ case 10: arch.SetTriple ("thumbv4t-apple-ios"); return true;
+ case 11: arch.SetTriple ("thumb-apple-ios"); return true;
+ default: break;
+ }
+ break;
+
case ArchSpec::eCore_arm_armv7:
switch (idx)
{
@@ -975,6 +1025,7 @@ PlatformDarwin::SetThreadCreationBreakpo
eFunctionNameTypeFull,
skip_prologue,
internal);
+ bp_sp->SetBreakpointKind("thread-creation");
return bp_sp;
}
Modified: lldb/branches/windows/source/Plugins/Platform/MacOSX/PlatformDarwin.h
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/windows/source/Plugins/Platform/MacOSX/PlatformDarwin.h?rev=179679&r1=179678&r2=179679&view=diff
==============================================================================
--- lldb/branches/windows/source/Plugins/Platform/MacOSX/PlatformDarwin.h (original)
+++ lldb/branches/windows/source/Plugins/Platform/MacOSX/PlatformDarwin.h Wed Apr 17 03:38:48 2013
@@ -38,8 +38,9 @@ public:
const lldb_private::ModuleSpec &sym_spec,
lldb_private::FileSpec &sym_file);
- lldb_private::FileSpec
- LocateExecutableScriptingResource (const lldb_private::ModuleSpec &module_spec);
+ lldb_private::FileSpecList
+ LocateExecutableScriptingResources (lldb_private::Target *target,
+ lldb_private::Module &module);
virtual lldb_private::Error
GetSharedModule (const lldb_private::ModuleSpec &module_spec,
Modified: lldb/branches/windows/source/Plugins/Process/CMakeLists.txt
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/windows/source/Plugins/Process/CMakeLists.txt?rev=179679&r1=179678&r2=179679&view=diff
==============================================================================
--- lldb/branches/windows/source/Plugins/Process/CMakeLists.txt (original)
+++ lldb/branches/windows/source/Plugins/Process/CMakeLists.txt Wed Apr 17 03:38:48 2013
@@ -1,7 +1,13 @@
-#add_subdirectory(FreeBSD)
+if(CMAKE_SYSTEM_NAME STREQUAL "FreeBSD")
+add_subdirectory(FreeBSD)
+endif()
add_subdirectory(gdb-remote)
-#add_subdirectory(Linux)
+if(CMAKE_SYSTEM_NAME STREQUAL "Linux")
+add_subdirectory(Linux)
+endif()
#add_subdirectory(mach-core)
#add_subdirectory(MacOSx-Kernel)
-#add_subdirectory(POSIX)
+if(NOT(CMAKE_SYSTEM_NAME STREQUAL "Windows"))
+add_subdirectory(POSIX)
+endif()
add_subdirectory(Utility)
Modified: lldb/branches/windows/source/Plugins/Process/FreeBSD/ProcessMonitor.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/windows/source/Plugins/Process/FreeBSD/ProcessMonitor.cpp?rev=179679&r1=179678&r2=179679&view=diff
==============================================================================
--- lldb/branches/windows/source/Plugins/Process/FreeBSD/ProcessMonitor.cpp (original)
+++ lldb/branches/windows/source/Plugins/Process/FreeBSD/ProcessMonitor.cpp Wed Apr 17 03:38:48 2013
@@ -58,13 +58,15 @@ Get_PT_IO_OP(int op)
}
}
+// Wrapper for ptrace to catch errors and log calls.
+// Note that ptrace sets errno on error because -1 is reserved as a valid result.
extern long
-PtraceWrapper(int req, ::pid_t pid, void *addr, int data,
+PtraceWrapper(int req, lldb::pid_t pid, void *addr, int data,
const char* reqName, const char* file, int line)
{
long int result;
- LogSP log (ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_PTRACE));
+ Log *log (ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_PTRACE));
if (log) {
log->Printf("ptrace(%s, %u, %p, %x) called from file %s line %d",
@@ -84,7 +86,7 @@ PtraceWrapper(int req, ::pid_t pid, void
//PtraceDisplayBytes(req, data);
- if (log && (result == -1 || errno != 0))
+ if (log && errno != 0)
{
const char* str;
switch (errno)
@@ -112,10 +114,21 @@ PtraceWrapper(int req, ::pid_t pid, void
return result;
}
+// Wrapper for ptrace when logging is not required.
+// Sets errno to 0 prior to calling ptrace.
+extern long
+PtraceWrapper(__ptrace_request req, lldb::pid_t pid, void *addr, int data)
+{
+ long result = 0;
+ errno = 0;
+ result = ptrace(req, pid, addr, data);
+ return result;
+}
+
#define PTRACE(req, pid, addr, data) \
PtraceWrapper((req), (pid), (addr), (data), #req, __FILE__, __LINE__)
#else
-#define PTRACE ptrace
+ PtraceWrapper((req), (pid), (addr), (data))
#endif
//------------------------------------------------------------------------------
@@ -627,14 +640,16 @@ ProcessMonitor::LaunchArgs::LaunchArgs(P
char const **envp,
const char *stdin_path,
const char *stdout_path,
- const char *stderr_path)
+ const char *stderr_path,
+ const char *working_dir)
: OperationArgs(monitor),
m_module(module),
m_argv(argv),
m_envp(envp),
m_stdin_path(stdin_path),
m_stdout_path(stdout_path),
- m_stderr_path(stderr_path) { }
+ m_stderr_path(stderr_path),
+ m_working_dir(working_dir) { }
ProcessMonitor::LaunchArgs::~LaunchArgs()
{ }
@@ -665,6 +680,7 @@ ProcessMonitor::ProcessMonitor(ProcessPO
const char *stdin_path,
const char *stdout_path,
const char *stderr_path,
+ const char *working_dir,
lldb_private::Error &error)
: m_process(static_cast<ProcessFreeBSD *>(process)),
m_operation_thread(LLDB_INVALID_HOST_THREAD),
@@ -678,7 +694,7 @@ ProcessMonitor::ProcessMonitor(ProcessPO
std::auto_ptr<LaunchArgs> args;
args.reset(new LaunchArgs(this, module, argv, envp,
- stdin_path, stdout_path, stderr_path));
+ stdin_path, stdout_path, stderr_path, working_dir));
// Server/client descriptors.
@@ -839,6 +855,7 @@ ProcessMonitor::Launch(LaunchArgs *args)
const char *stdin_path = args->m_stdin_path;
const char *stdout_path = args->m_stdout_path;
const char *stderr_path = args->m_stderr_path;
+ const char *working_dir = args->m_working_dir;
lldb::pid_t pid;
lldb::ThreadSP inferior;
@@ -853,6 +870,7 @@ ProcessMonitor::Launch(LaunchArgs *args)
eDupStdinFailed,
eDupStdoutFailed,
eDupStderrFailed,
+ eChdirFailed,
eExecFailed
};
@@ -887,6 +905,11 @@ ProcessMonitor::Launch(LaunchArgs *args)
if (!DupDescriptor(stderr_path, STDERR_FILENO, O_WRONLY | O_CREAT))
exit(eDupStderrFailed);
+ // Change working directory
+ if (working_dir != NULL && working_dir[0])
+ if (0 != ::chdir(working_dir))
+ exit(eChdirFailed);
+
// Execute. We should never return.
execve(argv[0],
const_cast<char *const *>(argv),
@@ -920,6 +943,9 @@ ProcessMonitor::Launch(LaunchArgs *args)
case eDupStderrFailed:
args->m_error.SetErrorString("Child open stderr failed.");
break;
+ case eChdirFailed:
+ args->m_error.SetErrorString("Child failed to set working directory.");
+ break;
case eExecFailed:
args->m_error.SetErrorString("Child exec failed.");
break;
@@ -1091,7 +1117,8 @@ ProcessMonitor::MonitorSIGTRAP(ProcessMo
{
ProcessMessage message;
- assert(info->si_signo == SIGTRAP && "Unexpected child signal!");
+ assert(monitor);
+ assert(info && info->si_signo == SIGTRAP && "Unexpected child signal!");
switch (info->si_code)
{
@@ -1430,7 +1457,7 @@ ProcessMonitor::WriteRegisterValue(lldb:
}
bool
-ProcessMonitor::ReadGPR(lldb::tid_t tid, void *buf)
+ProcessMonitor::ReadGPR(lldb::tid_t tid, void *buf, size_t buf_size)
{
bool result;
ReadGPROperation op(buf, result);
@@ -1439,7 +1466,7 @@ ProcessMonitor::ReadGPR(lldb::tid_t tid,
}
bool
-ProcessMonitor::ReadFPR(lldb::tid_t tid, void *buf)
+ProcessMonitor::ReadFPR(lldb::tid_t tid, void *buf, size_t buf_size)
{
bool result;
ReadFPROperation op(buf, result);
@@ -1448,7 +1475,7 @@ ProcessMonitor::ReadFPR(lldb::tid_t tid,
}
bool
-ProcessMonitor::WriteGPR(lldb::tid_t tid, void *buf)
+ProcessMonitor::WriteGPR(lldb::tid_t tid, void *buf, size_t buf_size)
{
bool result;
WriteGPROperation op(buf, result);
@@ -1457,7 +1484,7 @@ ProcessMonitor::WriteGPR(lldb::tid_t tid
}
bool
-ProcessMonitor::WriteFPR(lldb::tid_t tid, void *buf)
+ProcessMonitor::WriteFPR(lldb::tid_t tid, void *buf, size_t buf_size)
{
bool result;
WriteFPROperation op(buf, result);
Modified: lldb/branches/windows/source/Plugins/Process/FreeBSD/ProcessMonitor.h
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/windows/source/Plugins/Process/FreeBSD/ProcessMonitor.h?rev=179679&r1=179678&r2=179679&view=diff
==============================================================================
--- lldb/branches/windows/source/Plugins/Process/FreeBSD/ProcessMonitor.h (original)
+++ lldb/branches/windows/source/Plugins/Process/FreeBSD/ProcessMonitor.h Wed Apr 17 03:38:48 2013
@@ -54,6 +54,7 @@ public:
const char *stdin_path,
const char *stdout_path,
const char *stderr_path,
+ const char *working_dir,
lldb_private::Error &error);
ProcessMonitor(ProcessPOSIX *process,
@@ -123,19 +124,19 @@ public:
/// FIXME: The FreeBSD implementation of this function should use tid in order
/// to enable support for debugging threaded programs.
bool
- ReadGPR(lldb::tid_t tid, void *buf);
+ ReadGPR(lldb::tid_t tid, void *buf, size_t buf_size);
/// Reads all floating point registers into the specified buffer.
/// FIXME: The FreeBSD implementation of this function should use tid in order
/// to enable support for debugging threaded programs.
bool
- ReadFPR(lldb::tid_t tid, void *buf);
+ ReadFPR(lldb::tid_t tid, void *buf, size_t buf_size);
/// Writes all general purpose registers into the specified buffer.
/// FIXME: The FreeBSD implementation of this function should use tid in order
/// to enable support for debugging threaded programs.
bool
- WriteGPR(lldb::tid_t tid, void *buf);
+ WriteGPR(lldb::tid_t tid, void *buf, size_t buf_size);
/// Writes all floating point registers into the specified buffer.
/// FIXME: The FreeBSD implementation of this function should use tid in order
@@ -210,7 +211,8 @@ private:
char const **envp,
const char *stdin_path,
const char *stdout_path,
- const char *stderr_path);
+ const char *stderr_path,
+ const char *working_dir);
~LaunchArgs();
@@ -220,6 +222,7 @@ private:
const char *m_stdin_path; // Redirect stdin or NULL.
const char *m_stdout_path; // Redirect stdout or NULL.
const char *m_stderr_path; // Redirect stderr or NULL.
+ const char *m_working_dir; // Working directory or NULL.
};
void
Modified: lldb/branches/windows/source/Plugins/Process/Linux/ProcessLinux.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/windows/source/Plugins/Process/Linux/ProcessLinux.cpp?rev=179679&r1=179678&r2=179679&view=diff
==============================================================================
--- lldb/branches/windows/source/Plugins/Process/Linux/ProcessLinux.cpp (original)
+++ lldb/branches/windows/source/Plugins/Process/Linux/ProcessLinux.cpp Wed Apr 17 03:38:48 2013
@@ -97,22 +97,7 @@ ProcessLinux::GetPluginDescriptionStatic
bool
ProcessLinux::UpdateThreadList(ThreadList &old_thread_list, ThreadList &new_thread_list)
{
- LogSP log (ProcessPOSIXLog::GetLogIfAllCategoriesSet (POSIX_LOG_THREAD));
- if (log && log->GetMask().Test(POSIX_LOG_VERBOSE))
- log->Printf ("ProcessLinux::%s() (pid = %" PRIu64 ")", __FUNCTION__, GetID());
-
- // Update the process thread list with this new thread.
- // FIXME: We should be using tid, not pid.
- assert(m_monitor);
- ThreadSP thread_sp (old_thread_list.FindThreadByID (GetID(), false));
- if (!thread_sp) {
- thread_sp.reset(new POSIXThread(*this, GetID()));
- }
-
- if (log && log->GetMask().Test(POSIX_LOG_VERBOSE))
- log->Printf ("ProcessLinux::%s() updated pid = %" PRIu64, __FUNCTION__, GetID());
- new_thread_list.AddThread(thread_sp);
-
+ new_thread_list = old_thread_list;
return new_thread_list.GetSize(false) > 0;
}
Modified: lldb/branches/windows/source/Plugins/Process/Linux/ProcessMonitor.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/windows/source/Plugins/Process/Linux/ProcessMonitor.cpp?rev=179679&r1=179678&r2=179679&view=diff
==============================================================================
--- lldb/branches/windows/source/Plugins/Process/Linux/ProcessMonitor.cpp (original)
+++ lldb/branches/windows/source/Plugins/Process/Linux/ProcessMonitor.cpp Wed Apr 17 03:38:48 2013
@@ -18,7 +18,6 @@
#include <sys/ptrace.h>
#include <sys/socket.h>
#include <sys/types.h>
-#include <sys/user.h>
#include <sys/wait.h>
// C++ Includes
@@ -40,6 +39,14 @@
#define DEBUG_PTRACE_MAXBYTES 20
+// Support ptrace extensions even when compiled without required kernel support
+#ifndef PTRACE_GETREGSET
+ #define PTRACE_GETREGSET 0x4204
+#endif
+#ifndef PTRACE_SETREGSET
+ #define PTRACE_SETREGSET 0x4205
+#endif
+
using namespace lldb_private;
// FIXME: this code is host-dependent with respect to types and
@@ -64,10 +71,10 @@ DisplayBytes (lldb_private::StreamString
}
}
-static void PtraceDisplayBytes(__ptrace_request &req, void *data)
+static void PtraceDisplayBytes(int &req, void *data, size_t data_size)
{
StreamString buf;
- LogSP verbose_log (ProcessPOSIXLog::GetLogIfAllCategoriesSet (
+ Log *verbose_log (ProcessPOSIXLog::GetLogIfAllCategoriesSet (
POSIX_LOG_PTRACE | POSIX_LOG_VERBOSE));
if (verbose_log)
@@ -94,13 +101,13 @@ static void PtraceDisplayBytes(__ptrace_
}
case PTRACE_SETREGS:
{
- DisplayBytes(buf, data, sizeof(user_regs_struct));
+ DisplayBytes(buf, data, data_size);
verbose_log->Printf("PTRACE_SETREGS %s", buf.GetData());
break;
}
case PTRACE_SETFPREGS:
{
- DisplayBytes(buf, data, sizeof(user_fpregs_struct));
+ DisplayBytes(buf, data, data_size);
verbose_log->Printf("PTRACE_SETFPREGS %s", buf.GetData());
break;
}
@@ -110,6 +117,13 @@ static void PtraceDisplayBytes(__ptrace_
verbose_log->Printf("PTRACE_SETSIGINFO %s", buf.GetData());
break;
}
+ case PTRACE_SETREGSET:
+ {
+ // Extract iov_base from data, which is a pointer to the struct IOVEC
+ DisplayBytes(buf, *(void **)data, data_size);
+ verbose_log->Printf("PTRACE_SETREGSET %s", buf.GetData());
+ break;
+ }
default:
{
}
@@ -118,26 +132,30 @@ static void PtraceDisplayBytes(__ptrace_
}
// Wrapper for ptrace to catch errors and log calls.
+// Note that ptrace sets errno on error because -1 can be a valid result (i.e. for PTRACE_PEEK*)
extern long
-PtraceWrapper(__ptrace_request req, pid_t pid, void *addr, void *data,
+PtraceWrapper(int req, lldb::pid_t pid, void *addr, void *data, size_t data_size,
const char* reqName, const char* file, int line)
{
long int result;
- LogSP log (ProcessPOSIXLog::GetLogIfAllCategoriesSet (POSIX_LOG_PTRACE));
+ Log *log (ProcessPOSIXLog::GetLogIfAllCategoriesSet (POSIX_LOG_PTRACE));
if (log)
- log->Printf("ptrace(%s, %u, %p, %p) called from file %s line %d",
- reqName, pid, addr, data, file, line);
+ log->Printf("ptrace(%s, %lu, %p, %p, %zu) called from file %s line %d",
+ reqName, pid, addr, data, data_size, file, line);
- PtraceDisplayBytes(req, data);
+ PtraceDisplayBytes(req, data, data_size);
errno = 0;
- result = ptrace(req, pid, addr, data);
+ if (req == PTRACE_GETREGSET || req == PTRACE_SETREGSET)
+ result = ptrace(static_cast<__ptrace_request>(req), pid, *(unsigned int *)addr, data);
+ else
+ result = ptrace(static_cast<__ptrace_request>(req), pid, addr, data);
- PtraceDisplayBytes(req, data);
+ PtraceDisplayBytes(req, data, data_size);
- if (log && (result == -1 || errno != 0))
+ if (log && errno != 0)
{
const char* str;
switch (errno)
@@ -154,10 +172,24 @@ PtraceWrapper(__ptrace_request req, pid_
return result;
}
-#define PTRACE(req, pid, addr, data) \
- PtraceWrapper((req), (pid), (addr), (data), #req, __FILE__, __LINE__)
+// Wrapper for ptrace when logging is not required.
+// Sets errno to 0 prior to calling ptrace.
+extern long
+PtraceWrapper(int req, pid_t pid, void *addr, void *data, size_t data_size)
+{
+ long result = 0;
+ errno = 0;
+ if (req == PTRACE_GETREGSET || req == PTRACE_SETREGSET)
+ result = ptrace(static_cast<__ptrace_request>(req), pid, *(unsigned int *)addr, data);
+ else
+ result = ptrace(static_cast<__ptrace_request>(req), pid, addr, data);
+ return result;
+}
+
+#define PTRACE(req, pid, addr, data, data_size) \
+ PtraceWrapper((req), (pid), (addr), (data), (data_size), #req, __FILE__, __LINE__)
#else
-#define PTRACE ptrace
+ PtraceWrapper((req), (pid), (addr), (data), (data_size))
#endif
//------------------------------------------------------------------------------
@@ -176,7 +208,7 @@ DoReadMemory(lldb::pid_t pid,
size_t remainder;
long data;
- LogSP log (ProcessPOSIXLog::GetLogIfAllCategoriesSet (POSIX_LOG_ALL));
+ Log *log (ProcessPOSIXLog::GetLogIfAllCategoriesSet (POSIX_LOG_ALL));
if (log)
ProcessPOSIXLog::IncNestLevel();
if (log && ProcessPOSIXLog::AtTopNestLevel() && log->GetMask().Test(POSIX_LOG_MEMORY))
@@ -187,8 +219,8 @@ DoReadMemory(lldb::pid_t pid,
for (bytes_read = 0; bytes_read < size; bytes_read += remainder)
{
errno = 0;
- data = PTRACE(PTRACE_PEEKDATA, pid, (void*)vm_addr, NULL);
- if (data == -1L && errno)
+ data = PTRACE(PTRACE_PEEKDATA, pid, (void*)vm_addr, NULL, 0);
+ if (errno)
{
error.SetErrorToErrno();
if (log)
@@ -235,7 +267,7 @@ DoWriteMemory(lldb::pid_t pid,
size_t bytes_written = 0;
size_t remainder;
- LogSP log (ProcessPOSIXLog::GetLogIfAllCategoriesSet (POSIX_LOG_ALL));
+ Log *log (ProcessPOSIXLog::GetLogIfAllCategoriesSet (POSIX_LOG_ALL));
if (log)
ProcessPOSIXLog::IncNestLevel();
if (log && ProcessPOSIXLog::AtTopNestLevel() && log->GetMask().Test(POSIX_LOG_MEMORY))
@@ -261,7 +293,7 @@ DoWriteMemory(lldb::pid_t pid,
log->Printf ("ProcessMonitor::%s() [%p]:0x%lx (0x%lx)", __FUNCTION__,
(void*)vm_addr, *(unsigned long*)src, data);
- if (PTRACE(PTRACE_POKEDATA, pid, (void*)vm_addr, (void*)data))
+ if (PTRACE(PTRACE_POKEDATA, pid, (void*)vm_addr, (void*)data, 0))
{
error.SetErrorToErrno();
if (log)
@@ -430,12 +462,12 @@ private:
void
ReadRegOperation::Execute(ProcessMonitor *monitor)
{
- LogSP log (ProcessPOSIXLog::GetLogIfAllCategoriesSet (POSIX_LOG_REGISTERS));
+ Log *log (ProcessPOSIXLog::GetLogIfAllCategoriesSet (POSIX_LOG_REGISTERS));
// Set errno to zero so that we can detect a failed peek.
errno = 0;
- lldb::addr_t data = PTRACE(PTRACE_PEEKUSER, m_tid, (void*)m_offset, NULL);
- if (data == -1UL && errno)
+ lldb::addr_t data = PTRACE(PTRACE_PEEKUSER, m_tid, (void*)m_offset, NULL, 0);
+ if (errno)
m_result = false;
else
{
@@ -472,7 +504,7 @@ void
WriteRegOperation::Execute(ProcessMonitor *monitor)
{
void* buf;
- LogSP log (ProcessPOSIXLog::GetLogIfAllCategoriesSet (POSIX_LOG_REGISTERS));
+ Log *log (ProcessPOSIXLog::GetLogIfAllCategoriesSet (POSIX_LOG_REGISTERS));
#if __WORDSIZE == 32
buf = (void*) m_value.GetAsUInt32();
@@ -483,7 +515,7 @@ WriteRegOperation::Execute(ProcessMonito
if (log)
log->Printf ("ProcessMonitor::%s() reg %s: %p", __FUNCTION__,
POSIXThread::GetRegisterNameFromOffset(m_offset), buf);
- if (PTRACE(PTRACE_POKEUSER, m_tid, (void*)m_offset, buf))
+ if (PTRACE(PTRACE_POKEUSER, m_tid, (void*)m_offset, buf, 0))
m_result = false;
else
m_result = true;
@@ -495,8 +527,8 @@ WriteRegOperation::Execute(ProcessMonito
class ReadGPROperation : public Operation
{
public:
- ReadGPROperation(lldb::tid_t tid, void *buf, bool &result)
- : m_tid(tid), m_buf(buf), m_result(result)
+ ReadGPROperation(lldb::tid_t tid, void *buf, size_t buf_size, bool &result)
+ : m_tid(tid), m_buf(buf), m_buf_size(buf_size), m_result(result)
{ }
void Execute(ProcessMonitor *monitor);
@@ -504,13 +536,14 @@ public:
private:
lldb::tid_t m_tid;
void *m_buf;
+ size_t m_buf_size;
bool &m_result;
};
void
ReadGPROperation::Execute(ProcessMonitor *monitor)
{
- if (PTRACE(PTRACE_GETREGS, m_tid, NULL, m_buf) < 0)
+ if (PTRACE(PTRACE_GETREGS, m_tid, NULL, m_buf, m_buf_size) < 0)
m_result = false;
else
m_result = true;
@@ -522,8 +555,8 @@ ReadGPROperation::Execute(ProcessMonitor
class ReadFPROperation : public Operation
{
public:
- ReadFPROperation(lldb::tid_t tid, void *buf, bool &result)
- : m_tid(tid), m_buf(buf), m_result(result)
+ ReadFPROperation(lldb::tid_t tid, void *buf, size_t buf_size, bool &result)
+ : m_tid(tid), m_buf(buf), m_buf_size(buf_size), m_result(result)
{ }
void Execute(ProcessMonitor *monitor);
@@ -531,13 +564,43 @@ public:
private:
lldb::tid_t m_tid;
void *m_buf;
+ size_t m_buf_size;
bool &m_result;
};
void
ReadFPROperation::Execute(ProcessMonitor *monitor)
{
- if (PTRACE(PTRACE_GETFPREGS, m_tid, NULL, m_buf) < 0)
+ if (PTRACE(PTRACE_GETFPREGS, m_tid, NULL, m_buf, m_buf_size) < 0)
+ m_result = false;
+ else
+ m_result = true;
+}
+
+//------------------------------------------------------------------------------
+/// @class ReadRegisterSetOperation
+/// @brief Implements ProcessMonitor::ReadRegisterSet.
+class ReadRegisterSetOperation : public Operation
+{
+public:
+ ReadRegisterSetOperation(lldb::tid_t tid, void *buf, size_t buf_size, unsigned int regset, bool &result)
+ : m_tid(tid), m_buf(buf), m_buf_size(buf_size), m_regset(regset), m_result(result)
+ { }
+
+ void Execute(ProcessMonitor *monitor);
+
+private:
+ lldb::tid_t m_tid;
+ void *m_buf;
+ size_t m_buf_size;
+ const unsigned int m_regset;
+ bool &m_result;
+};
+
+void
+ReadRegisterSetOperation::Execute(ProcessMonitor *monitor)
+{
+ if (PTRACE(PTRACE_GETREGSET, m_tid, (void *)&m_regset, m_buf, m_buf_size) < 0)
m_result = false;
else
m_result = true;
@@ -549,8 +612,8 @@ ReadFPROperation::Execute(ProcessMonitor
class WriteGPROperation : public Operation
{
public:
- WriteGPROperation(lldb::tid_t tid, void *buf, bool &result)
- : m_tid(tid), m_buf(buf), m_result(result)
+ WriteGPROperation(lldb::tid_t tid, void *buf, size_t buf_size, bool &result)
+ : m_tid(tid), m_buf(buf), m_buf_size(buf_size), m_result(result)
{ }
void Execute(ProcessMonitor *monitor);
@@ -558,13 +621,14 @@ public:
private:
lldb::tid_t m_tid;
void *m_buf;
+ size_t m_buf_size;
bool &m_result;
};
void
WriteGPROperation::Execute(ProcessMonitor *monitor)
{
- if (PTRACE(PTRACE_SETREGS, m_tid, NULL, m_buf) < 0)
+ if (PTRACE(PTRACE_SETREGS, m_tid, NULL, m_buf, m_buf_size) < 0)
m_result = false;
else
m_result = true;
@@ -576,8 +640,8 @@ WriteGPROperation::Execute(ProcessMonito
class WriteFPROperation : public Operation
{
public:
- WriteFPROperation(lldb::tid_t tid, void *buf, bool &result)
- : m_tid(tid), m_buf(buf), m_result(result)
+ WriteFPROperation(lldb::tid_t tid, void *buf, size_t buf_size, bool &result)
+ : m_tid(tid), m_buf(buf), m_buf_size(buf_size), m_result(result)
{ }
void Execute(ProcessMonitor *monitor);
@@ -585,13 +649,43 @@ public:
private:
lldb::tid_t m_tid;
void *m_buf;
+ size_t m_buf_size;
bool &m_result;
};
void
WriteFPROperation::Execute(ProcessMonitor *monitor)
{
- if (PTRACE(PTRACE_SETFPREGS, m_tid, NULL, m_buf) < 0)
+ if (PTRACE(PTRACE_SETFPREGS, m_tid, NULL, m_buf, m_buf_size) < 0)
+ m_result = false;
+ else
+ m_result = true;
+}
+
+//------------------------------------------------------------------------------
+/// @class WriteRegisterSetOperation
+/// @brief Implements ProcessMonitor::WriteRegisterSet.
+class WriteRegisterSetOperation : public Operation
+{
+public:
+ WriteRegisterSetOperation(lldb::tid_t tid, void *buf, size_t buf_size, unsigned int regset, bool &result)
+ : m_tid(tid), m_buf(buf), m_buf_size(buf_size), m_regset(regset), m_result(result)
+ { }
+
+ void Execute(ProcessMonitor *monitor);
+
+private:
+ lldb::tid_t m_tid;
+ void *m_buf;
+ size_t m_buf_size;
+ const unsigned int m_regset;
+ bool &m_result;
+};
+
+void
+WriteRegisterSetOperation::Execute(ProcessMonitor *monitor)
+{
+ if (PTRACE(PTRACE_SETREGSET, m_tid, (void *)&m_regset, m_buf, m_buf_size) < 0)
m_result = false;
else
m_result = true;
@@ -622,7 +716,7 @@ ResumeOperation::Execute(ProcessMonitor
if (m_signo != LLDB_INVALID_SIGNAL_NUMBER)
data = m_signo;
- if (PTRACE(PTRACE_CONT, m_tid, NULL, (void*)data))
+ if (PTRACE(PTRACE_CONT, m_tid, NULL, (void*)data, 0))
m_result = false;
else
m_result = true;
@@ -653,7 +747,7 @@ SingleStepOperation::Execute(ProcessMoni
if (m_signo != LLDB_INVALID_SIGNAL_NUMBER)
data = m_signo;
- if (PTRACE(PTRACE_SINGLESTEP, m_tid, NULL, (void*)data))
+ if (PTRACE(PTRACE_SINGLESTEP, m_tid, NULL, (void*)data, 0))
m_result = false;
else
m_result = true;
@@ -680,7 +774,7 @@ private:
void
SiginfoOperation::Execute(ProcessMonitor *monitor)
{
- if (PTRACE(PTRACE_GETSIGINFO, m_tid, NULL, m_info)) {
+ if (PTRACE(PTRACE_GETSIGINFO, m_tid, NULL, m_info, 0)) {
m_result = false;
m_err = errno;
}
@@ -708,7 +802,7 @@ private:
void
EventMessageOperation::Execute(ProcessMonitor *monitor)
{
- if (PTRACE(PTRACE_GETEVENTMSG, m_tid, NULL, m_message))
+ if (PTRACE(PTRACE_GETEVENTMSG, m_tid, NULL, m_message, 0))
m_result = false;
else
m_result = true;
@@ -733,7 +827,7 @@ KillOperation::Execute(ProcessMonitor *m
{
lldb::pid_t pid = monitor->GetPID();
- if (PTRACE(PTRACE_KILL, pid, NULL, NULL))
+ if (PTRACE(PTRACE_KILL, pid, NULL, NULL, 0))
m_result = false;
else
m_result = true;
@@ -780,14 +874,16 @@ ProcessMonitor::LaunchArgs::LaunchArgs(P
char const **envp,
const char *stdin_path,
const char *stdout_path,
- const char *stderr_path)
+ const char *stderr_path,
+ const char *working_dir)
: OperationArgs(monitor),
m_module(module),
m_argv(argv),
m_envp(envp),
m_stdin_path(stdin_path),
m_stdout_path(stdout_path),
- m_stderr_path(stderr_path) { }
+ m_stderr_path(stderr_path),
+ m_working_dir(working_dir) { }
ProcessMonitor::LaunchArgs::~LaunchArgs()
{ }
@@ -818,19 +914,20 @@ ProcessMonitor::ProcessMonitor(ProcessPO
const char *stdin_path,
const char *stdout_path,
const char *stderr_path,
+ const char *working_dir,
lldb_private::Error &error)
: m_process(static_cast<ProcessLinux *>(process)),
m_operation_thread(LLDB_INVALID_HOST_THREAD),
+ m_monitor_thread(LLDB_INVALID_HOST_THREAD),
m_pid(LLDB_INVALID_PROCESS_ID),
m_terminal_fd(-1),
- m_monitor_thread(LLDB_INVALID_HOST_THREAD),
m_client_fd(-1),
m_server_fd(-1)
{
std::auto_ptr<LaunchArgs> args;
args.reset(new LaunchArgs(this, module, argv, envp,
- stdin_path, stdout_path, stderr_path));
+ stdin_path, stdout_path, stderr_path, working_dir));
// Server/client descriptors.
if (!EnableIPC())
@@ -880,9 +977,10 @@ ProcessMonitor::ProcessMonitor(ProcessPO
lldb_private::Error &error)
: m_process(static_cast<ProcessLinux *>(process)),
m_operation_thread(LLDB_INVALID_HOST_THREAD),
+ m_monitor_thread(LLDB_INVALID_HOST_THREAD),
m_pid(LLDB_INVALID_PROCESS_ID),
m_terminal_fd(-1),
- m_monitor_thread(LLDB_INVALID_HOST_THREAD),
+
m_client_fd(-1),
m_server_fd(-1)
{
@@ -976,14 +1074,16 @@ ProcessMonitor::Launch(LaunchArgs *args)
const char *stdin_path = args->m_stdin_path;
const char *stdout_path = args->m_stdout_path;
const char *stderr_path = args->m_stderr_path;
+ const char *working_dir = args->m_working_dir;
lldb_utility::PseudoTerminal terminal;
const size_t err_len = 1024;
char err_str[err_len];
lldb::pid_t pid;
+ long ptrace_opts = 0;
lldb::ThreadSP inferior;
- LogSP log (ProcessPOSIXLog::GetLogIfAllCategoriesSet (POSIX_LOG_PROCESS));
+ Log *log (ProcessPOSIXLog::GetLogIfAllCategoriesSet (POSIX_LOG_PROCESS));
// Propagate the environment if one is not supplied.
if (envp == NULL || envp[0] == NULL)
@@ -1010,6 +1110,7 @@ ProcessMonitor::Launch(LaunchArgs *args)
eDupStdinFailed,
eDupStdoutFailed,
eDupStderrFailed,
+ eChdirFailed,
eExecFailed
};
@@ -1017,7 +1118,7 @@ ProcessMonitor::Launch(LaunchArgs *args)
if (pid == 0)
{
// Trace this process.
- if (PTRACE(PTRACE_TRACEME, 0, NULL, NULL) < 0)
+ if (PTRACE(PTRACE_TRACEME, 0, NULL, NULL, 0) < 0)
exit(ePtraceFailed);
// Do not inherit setgid powers.
@@ -1042,6 +1143,11 @@ ProcessMonitor::Launch(LaunchArgs *args)
if (!DupDescriptor(stderr_path, STDERR_FILENO, O_WRONLY | O_CREAT))
exit(eDupStderrFailed);
+ // Change working directory
+ if (working_dir != NULL && working_dir[0])
+ if (0 != ::chdir(working_dir))
+ exit(eChdirFailed);
+
// Execute. We should never return.
execve(argv[0],
const_cast<char *const *>(argv),
@@ -1075,6 +1181,9 @@ ProcessMonitor::Launch(LaunchArgs *args)
case eDupStderrFailed:
args->m_error.SetErrorString("Child open stderr failed.");
break;
+ case eChdirFailed:
+ args->m_error.SetErrorString("Child failed to set working directory.");
+ break;
case eExecFailed:
args->m_error.SetErrorString("Child exec failed.");
break;
@@ -1089,7 +1198,12 @@ ProcessMonitor::Launch(LaunchArgs *args)
// Have the child raise an event on exit. This is used to keep the child in
// limbo until it is destroyed.
- if (PTRACE(PTRACE_SETOPTIONS, pid, NULL, (void*)PTRACE_O_TRACEEXIT) < 0)
+ ptrace_opts |= PTRACE_O_TRACEEXIT;
+
+ // Have the tracer trace threads which spawn in the inferior process.
+ ptrace_opts |= PTRACE_O_TRACEFORK | PTRACE_O_TRACEVFORK | PTRACE_O_TRACECLONE;
+
+ if (PTRACE(PTRACE_SETOPTIONS, pid, NULL, (void*)ptrace_opts, 0) < 0)
{
args->m_error.SetErrorToErrno();
goto FINISH;
@@ -1168,7 +1282,7 @@ ProcessMonitor::Attach(AttachArgs *args)
ProcessMonitor *monitor = args->m_monitor;
ProcessLinux &process = monitor->GetProcess();
lldb::ThreadSP inferior;
- LogSP log (ProcessPOSIXLog::GetLogIfAllCategoriesSet (POSIX_LOG_PROCESS));
+ Log *log (ProcessPOSIXLog::GetLogIfAllCategoriesSet (POSIX_LOG_PROCESS));
if (pid <= 1)
{
@@ -1178,7 +1292,7 @@ ProcessMonitor::Attach(AttachArgs *args)
}
// Attach to the requested process.
- if (PTRACE(PTRACE_ATTACH, pid, NULL, NULL) < 0)
+ if (PTRACE(PTRACE_ATTACH, pid, NULL, NULL, 0) < 0)
{
args->m_error.SetErrorToErrno();
goto FINISH;
@@ -1269,6 +1383,17 @@ ProcessMonitor::MonitorSIGTRAP(ProcessMo
assert(false && "Unexpected SIGTRAP code!");
break;
+ case (SIGTRAP | (PTRACE_EVENT_FORK << 8)):
+ case (SIGTRAP | (PTRACE_EVENT_VFORK << 8)):
+ case (SIGTRAP | (PTRACE_EVENT_CLONE << 8)):
+ {
+ unsigned long tid = 0;
+ if (!monitor->GetEventMessage(pid, &tid))
+ tid = -1;
+ message = ProcessMessage::NewThread(pid, tid);
+ break;
+ }
+
case (SIGTRAP | (PTRACE_EVENT_EXIT << 8)):
{
// The inferior process is about to exit. Maintain the process in a
@@ -1526,7 +1651,8 @@ ProcessMonitor::ServeOperation(Operation
assert(errno == EINTR);
goto READ_AGAIN;
}
-
+ if (status == 0)
+ continue; // Poll again. The connection probably terminated.
assert(status == sizeof(op));
op->Execute(monitor);
write(fdset.fd, &op, sizeof(op));
@@ -1580,7 +1706,8 @@ ProcessMonitor::WriteMemory(lldb::addr_t
}
bool
-ProcessMonitor::ReadRegisterValue(lldb::tid_t tid, unsigned offset, unsigned size, RegisterValue &value)
+ProcessMonitor::ReadRegisterValue(lldb::tid_t tid, unsigned offset,
+ unsigned size, RegisterValue &value)
{
bool result;
ReadRegOperation op(tid, offset, value, result);
@@ -1589,7 +1716,8 @@ ProcessMonitor::ReadRegisterValue(lldb::
}
bool
-ProcessMonitor::WriteRegisterValue(lldb::tid_t tid, unsigned offset, const RegisterValue &value)
+ProcessMonitor::WriteRegisterValue(lldb::tid_t tid, unsigned offset,
+ const RegisterValue &value)
{
bool result;
WriteRegOperation op(tid, offset, value, result);
@@ -1598,37 +1726,55 @@ ProcessMonitor::WriteRegisterValue(lldb:
}
bool
-ProcessMonitor::ReadGPR(lldb::tid_t tid, void *buf)
+ProcessMonitor::ReadGPR(lldb::tid_t tid, void *buf, size_t buf_size)
+{
+ bool result;
+ ReadGPROperation op(tid, buf, buf_size, result);
+ DoOperation(&op);
+ return result;
+}
+
+bool
+ProcessMonitor::ReadFPR(lldb::tid_t tid, void *buf, size_t buf_size)
+{
+ bool result;
+ ReadFPROperation op(tid, buf, buf_size, result);
+ DoOperation(&op);
+ return result;
+}
+
+bool
+ProcessMonitor::ReadRegisterSet(lldb::tid_t tid, void *buf, size_t buf_size, unsigned int regset)
{
bool result;
- ReadGPROperation op(tid, buf, result);
+ ReadRegisterSetOperation op(tid, buf, buf_size, regset, result);
DoOperation(&op);
return result;
}
bool
-ProcessMonitor::ReadFPR(lldb::tid_t tid, void *buf)
+ProcessMonitor::WriteGPR(lldb::tid_t tid, void *buf, size_t buf_size)
{
bool result;
- ReadFPROperation op(tid, buf, result);
+ WriteGPROperation op(tid, buf, buf_size, result);
DoOperation(&op);
return result;
}
bool
-ProcessMonitor::WriteGPR(lldb::tid_t tid, void *buf)
+ProcessMonitor::WriteFPR(lldb::tid_t tid, void *buf, size_t buf_size)
{
bool result;
- WriteGPROperation op(tid, buf, result);
+ WriteFPROperation op(tid, buf, buf_size, result);
DoOperation(&op);
return result;
}
bool
-ProcessMonitor::WriteFPR(lldb::tid_t tid, void *buf)
+ProcessMonitor::WriteRegisterSet(lldb::tid_t tid, void *buf, size_t buf_size, unsigned int regset)
{
bool result;
- WriteFPROperation op(tid, buf, result);
+ WriteRegisterSetOperation op(tid, buf, buf_size, regset, result);
DoOperation(&op);
return result;
}
Modified: lldb/branches/windows/source/Plugins/Process/Linux/ProcessMonitor.h
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/windows/source/Plugins/Process/Linux/ProcessMonitor.h?rev=179679&r1=179678&r2=179679&view=diff
==============================================================================
--- lldb/branches/windows/source/Plugins/Process/Linux/ProcessMonitor.h (original)
+++ lldb/branches/windows/source/Plugins/Process/Linux/ProcessMonitor.h Wed Apr 17 03:38:48 2013
@@ -56,6 +56,7 @@ public:
const char *stdin_path,
const char *stdout_path,
const char *stderr_path,
+ const char *working_dir,
lldb_private::Error &error);
ProcessMonitor(ProcessPOSIX *process,
@@ -119,19 +120,29 @@ public:
/// Reads all general purpose registers into the specified buffer.
bool
- ReadGPR(lldb::tid_t tid, void *buf);
+ ReadGPR(lldb::tid_t tid, void *buf, size_t buf_size);
- /// Reads all floating point registers into the specified buffer.
+ /// Reads generic floating point registers into the specified buffer.
bool
- ReadFPR(lldb::tid_t tid, void *buf);
+ ReadFPR(lldb::tid_t tid, void *buf, size_t buf_size);
+
+ /// Reads the specified register set into the specified buffer.
+ /// For instance, the extended floating-point register set.
+ bool
+ ReadRegisterSet(lldb::tid_t tid, void *buf, size_t buf_size, unsigned int regset);
/// Writes all general purpose registers into the specified buffer.
bool
- WriteGPR(lldb::tid_t tid, void *buf);
+ WriteGPR(lldb::tid_t tid, void *buf, size_t buf_size);
+
+ /// Writes generic floating point registers into the specified buffer.
+ bool
+ WriteFPR(lldb::tid_t tid, void *buf, size_t buf_size);
- /// Writes all floating point registers into the specified buffer.
+ /// Writes the specified register set into the specified buffer.
+ /// For instance, the extended floating-point register set.
bool
- WriteFPR(lldb::tid_t tid, void *buf);
+ WriteRegisterSet(lldb::tid_t tid, void *buf, size_t buf_size, unsigned int regset);
/// Writes a siginfo_t structure corresponding to the given thread ID to the
/// memory region pointed to by @p siginfo.
@@ -168,10 +179,10 @@ private:
ProcessLinux *m_process;
lldb::thread_t m_operation_thread;
+ lldb::thread_t m_monitor_thread;
lldb::pid_t m_pid;
int m_terminal_fd;
- lldb::thread_t m_monitor_thread;
lldb_private::Mutex m_server_mutex;
int m_client_fd;
@@ -200,7 +211,8 @@ private:
char const **envp,
const char *stdin_path,
const char *stdout_path,
- const char *stderr_path);
+ const char *stderr_path,
+ const char *working_dir);
~LaunchArgs();
@@ -210,6 +222,7 @@ private:
const char *m_stdin_path; // Redirect stdin or NULL.
const char *m_stdout_path; // Redirect stdout or NULL.
const char *m_stderr_path; // Redirect stderr or NULL.
+ const char *m_working_dir; // Working directory or NULL.
};
void
Modified: lldb/branches/windows/source/Plugins/Process/MacOSX-Kernel/CommunicationKDP.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/windows/source/Plugins/Process/MacOSX-Kernel/CommunicationKDP.cpp?rev=179679&r1=179678&r2=179679&view=diff
==============================================================================
--- lldb/branches/windows/source/Plugins/Process/MacOSX-Kernel/CommunicationKDP.cpp (original)
+++ lldb/branches/windows/source/Plugins/Process/MacOSX-Kernel/CommunicationKDP.cpp Wed Apr 17 03:38:48 2013
@@ -97,13 +97,12 @@ CommunicationKDP::MakeRequestPacketHeade
bool
CommunicationKDP::SendRequestAndGetReply (const CommandType command,
- const uint8_t request_sequence_id,
- const PacketStreamType &request_packet,
+ const PacketStreamType &request_packet,
DataExtractor &reply_packet)
{
if (IsRunning())
{
- LogSP log (ProcessKDPLog::GetLogIfAllCategoriesSet (KDP_LOG_PACKETS));
+ Log *log (ProcessKDPLog::GetLogIfAllCategoriesSet (KDP_LOG_PACKETS));
if (log)
{
PacketStreamType log_strm;
@@ -118,20 +117,26 @@ CommunicationKDP::SendRequestAndGetReply
// NOTE: this only works for packets that are in native endian byte order
assert (request_packet.GetSize() == *((uint16_t *)(request_packet.GetData() + 2)));
#endif
- if (SendRequestPacketNoLock(request_packet))
+ lldb::offset_t offset = 1;
+ const uint32_t num_retries = 3;
+ for (uint32_t i=0; i<num_retries; ++i)
{
- if (WaitForPacketWithTimeoutMicroSecondsNoLock (reply_packet, GetPacketTimeoutInMicroSeconds ()))
+ if (SendRequestPacketNoLock(request_packet))
{
- uint32_t offset = 0;
- const uint8_t reply_command = reply_packet.GetU8 (&offset);
- const uint8_t reply_sequence_id = reply_packet.GetU8 (&offset);
- if ((reply_command & eCommandTypeMask) == command)
+ const uint8_t request_sequence_id = (uint8_t)request_packet.GetData()[1];
+ if (WaitForPacketWithTimeoutMicroSecondsNoLock (reply_packet, GetPacketTimeoutInMicroSeconds ()))
{
- if (request_sequence_id == reply_sequence_id)
+ offset = 0;
+ const uint8_t reply_command = reply_packet.GetU8 (&offset);
+ const uint8_t reply_sequence_id = reply_packet.GetU8 (&offset);
+ if ((reply_command & eCommandTypeMask) == command)
{
- if (command == KDP_RESUMECPUS)
- m_is_running.SetValue(true, eBroadcastAlways);
- return true;
+ if (request_sequence_id == reply_sequence_id)
+ {
+ if (command == KDP_RESUMECPUS)
+ m_is_running.SetValue(true, eBroadcastAlways);
+ return true;
+ }
}
}
}
@@ -148,7 +153,7 @@ CommunicationKDP::SendRequestPacketNoLoc
const char *packet_data = request_packet.GetData();
const size_t packet_size = request_packet.GetSize();
- LogSP log (ProcessKDPLog::GetLogIfAllCategoriesSet (KDP_LOG_PACKETS));
+ Log *log (ProcessKDPLog::GetLogIfAllCategoriesSet (KDP_LOG_PACKETS));
if (log)
{
PacketStreamType log_strm;
@@ -197,7 +202,7 @@ CommunicationKDP::WaitForPacketWithTimeo
uint8_t buffer[8192];
Error error;
- LogSP log (ProcessKDPLog::GetLogIfAllCategoriesSet (KDP_LOG_PACKETS | KDP_LOG_VERBOSE));
+ Log *log (ProcessKDPLog::GetLogIfAllCategoriesSet (KDP_LOG_PACKETS | KDP_LOG_VERBOSE));
// Check for a packet from our cache first without trying any reading...
if (CheckForPacket (NULL, 0, packet))
@@ -252,7 +257,7 @@ CommunicationKDP::CheckForPacket (const
// Put the packet data into the buffer in a thread safe fashion
Mutex::Locker locker(m_bytes_mutex);
- LogSP log (ProcessKDPLog::GetLogIfAllCategoriesSet (KDP_LOG_PACKETS));
+ Log *log (ProcessKDPLog::GetLogIfAllCategoriesSet (KDP_LOG_PACKETS));
if (src && src_len > 0)
{
@@ -273,7 +278,7 @@ CommunicationKDP::CheckForPacket (const
if (bytes_available >= 8)
{
packet.SetData (&m_bytes[0], bytes_available, m_byte_order);
- uint32_t offset = 0;
+ lldb::offset_t offset = 0;
uint8_t reply_command = packet.GetU8(&offset);
switch (reply_command)
{
@@ -315,6 +320,13 @@ CommunicationKDP::CheckForPacket (const
case ePacketTypeReply | KDP_BREAKPOINT_SET64:
case ePacketTypeReply | KDP_BREAKPOINT_REMOVE64:
case ePacketTypeReply | KDP_KERNELVERSION:
+ case ePacketTypeReply | KDP_READPHYSMEM64:
+ case ePacketTypeReply | KDP_WRITEPHYSMEM64:
+ case ePacketTypeReply | KDP_READIOPORT:
+ case ePacketTypeReply | KDP_WRITEIOPORT:
+ case ePacketTypeReply | KDP_READMSR64:
+ case ePacketTypeReply | KDP_WRITEMSR64:
+ case ePacketTypeReply | KDP_DUMPINFO:
{
offset = 2;
const uint16_t length = packet.GetU16 (&offset);
@@ -365,7 +377,6 @@ CommunicationKDP::SendRequestConnect (ui
const CommandType command = KDP_CONNECT;
// Length is 82 uint16_t and the length of the greeting C string with the terminating NULL
const uint32_t command_length = 8 + 2 + 2 + ::strlen(greeting) + 1;
- const uint32_t request_sequence_id = m_request_sequence_id;
MakeRequestPacketHeader (command, request_packet, command_length);
// Always send connect ports as little endian
request_packet.SetByteOrder (eByteOrderLittle);
@@ -374,7 +385,7 @@ CommunicationKDP::SendRequestConnect (ui
request_packet.SetByteOrder (m_byte_order);
request_packet.PutCString (greeting);
DataExtractor reply_packet;
- return SendRequestAndGetReply (command, request_sequence_id, request_packet, reply_packet);
+ return SendRequestAndGetReply (command, request_packet, reply_packet);
}
void
@@ -395,18 +406,17 @@ CommunicationKDP::SendRequestReattach (u
const CommandType command = KDP_REATTACH;
// Length is 8 bytes for the header plus 2 bytes for the reply UDP port
const uint32_t command_length = 8 + 2;
- const uint32_t request_sequence_id = m_request_sequence_id;
MakeRequestPacketHeader (command, request_packet, command_length);
// Always send connect ports as little endian
request_packet.SetByteOrder (eByteOrderLittle);
request_packet.PutHex16(reply_port);
request_packet.SetByteOrder (m_byte_order);
DataExtractor reply_packet;
- if (SendRequestAndGetReply (command, request_sequence_id, request_packet, reply_packet))
+ if (SendRequestAndGetReply (command, request_packet, reply_packet))
{
// Reset the sequence ID to zero for reattach
ClearKDPSettings ();
- uint32_t offset = 4;
+ lldb::offset_t offset = 4;
m_session_key = reply_packet.GetU32 (&offset);
return true;
}
@@ -435,12 +445,11 @@ CommunicationKDP::SendRequestVersion ()
PacketStreamType request_packet (Stream::eBinary, m_addr_byte_size, m_byte_order);
const CommandType command = KDP_VERSION;
const uint32_t command_length = 8;
- const uint32_t request_sequence_id = m_request_sequence_id;
MakeRequestPacketHeader (command, request_packet, command_length);
DataExtractor reply_packet;
- if (SendRequestAndGetReply (command, request_sequence_id, request_packet, reply_packet))
+ if (SendRequestAndGetReply (command, request_packet, reply_packet))
{
- uint32_t offset = 8;
+ lldb::offset_t offset = 8;
m_kdp_version_version = reply_packet.GetU32 (&offset);
m_kdp_version_feature = reply_packet.GetU32 (&offset);
return true;
@@ -463,10 +472,9 @@ CommunicationKDP::SendRequestImagePath (
PacketStreamType request_packet (Stream::eBinary, m_addr_byte_size, m_byte_order);
const CommandType command = KDP_IMAGEPATH;
const uint32_t command_length = 8;
- const uint32_t request_sequence_id = m_request_sequence_id;
MakeRequestPacketHeader (command, request_packet, command_length);
DataExtractor reply_packet;
- if (SendRequestAndGetReply (command, request_sequence_id, request_packet, reply_packet))
+ if (SendRequestAndGetReply (command, request_packet, reply_packet))
{
const char *path = reply_packet.PeekCStr(8);
if (path && path[0])
@@ -563,12 +571,11 @@ CommunicationKDP::SendRequestHostInfo ()
PacketStreamType request_packet (Stream::eBinary, m_addr_byte_size, m_byte_order);
const CommandType command = KDP_HOSTINFO;
const uint32_t command_length = 8;
- const uint32_t request_sequence_id = m_request_sequence_id;
MakeRequestPacketHeader (command, request_packet, command_length);
DataExtractor reply_packet;
- if (SendRequestAndGetReply (command, request_sequence_id, request_packet, reply_packet))
+ if (SendRequestAndGetReply (command, request_packet, reply_packet))
{
- uint32_t offset = 8;
+ lldb::offset_t offset = 8;
m_kdp_hostinfo_cpu_mask = reply_packet.GetU32 (&offset);
m_kdp_hostinfo_cpu_type = reply_packet.GetU32 (&offset);
m_kdp_hostinfo_cpu_subtype = reply_packet.GetU32 (&offset);
@@ -599,10 +606,9 @@ CommunicationKDP::SendRequestKernelVersi
PacketStreamType request_packet (Stream::eBinary, m_addr_byte_size, m_byte_order);
const CommandType command = KDP_KERNELVERSION;
const uint32_t command_length = 8;
- const uint32_t request_sequence_id = m_request_sequence_id;
MakeRequestPacketHeader (command, request_packet, command_length);
DataExtractor reply_packet;
- if (SendRequestAndGetReply (command, request_sequence_id, request_packet, reply_packet))
+ if (SendRequestAndGetReply (command, request_packet, reply_packet))
{
const char *kernel_version_cstr = reply_packet.PeekCStr(8);
if (kernel_version_cstr && kernel_version_cstr[0])
@@ -618,10 +624,9 @@ CommunicationKDP::SendRequestDisconnect
PacketStreamType request_packet (Stream::eBinary, m_addr_byte_size, m_byte_order);
const CommandType command = KDP_DISCONNECT;
const uint32_t command_length = 8;
- const uint32_t request_sequence_id = m_request_sequence_id;
MakeRequestPacketHeader (command, request_packet, command_length);
DataExtractor reply_packet;
- if (SendRequestAndGetReply (command, request_sequence_id, request_packet, reply_packet))
+ if (SendRequestAndGetReply (command, request_packet, reply_packet))
{
// Are we supposed to get a reply for disconnect?
}
@@ -641,14 +646,13 @@ CommunicationKDP::SendRequestReadMemory
const CommandType command = use_64 ? KDP_READMEM64 : KDP_READMEM;
// Size is header + address size + uint32_t length
const uint32_t command_length = 8 + command_addr_byte_size + 4;
- const uint32_t request_sequence_id = m_request_sequence_id;
MakeRequestPacketHeader (command, request_packet, command_length);
request_packet.PutMaxHex64 (addr, command_addr_byte_size);
request_packet.PutHex32 (dst_len);
DataExtractor reply_packet;
- if (SendRequestAndGetReply (command, request_sequence_id, request_packet, reply_packet))
+ if (SendRequestAndGetReply (command, request_packet, reply_packet))
{
- uint32_t offset = 8;
+ lldb::offset_t offset = 8;
uint32_t kdp_error = reply_packet.GetU32 (&offset);
uint32_t src_len = reply_packet.GetByteSize() - 12;
@@ -687,16 +691,15 @@ CommunicationKDP::SendRequestWriteMemory
const CommandType command = use_64 ? KDP_WRITEMEM64 : KDP_WRITEMEM;
// Size is header + address size + uint32_t length
const uint32_t command_length = 8 + command_addr_byte_size + 4 + src_len;
- const uint32_t request_sequence_id = m_request_sequence_id;
MakeRequestPacketHeader (command, request_packet, command_length);
request_packet.PutMaxHex64 (addr, command_addr_byte_size);
request_packet.PutHex32 (src_len);
request_packet.PutRawBytes(src, src_len);
DataExtractor reply_packet;
- if (SendRequestAndGetReply (command, request_sequence_id, request_packet, reply_packet))
+ if (SendRequestAndGetReply (command, request_packet, reply_packet))
{
- uint32_t offset = 8;
+ lldb::offset_t offset = 8;
uint32_t kdp_error = reply_packet.GetU32 (&offset);
if (kdp_error)
error.SetErrorStringWithFormat ("kdp write memory failed (error %u)", kdp_error);
@@ -724,15 +727,14 @@ CommunicationKDP::SendRawRequest (uint8_
// Size is header + address size + uint32_t length
const uint32_t command_length = 8 + src_len;
const CommandType command = (CommandType)command_byte;
- const uint32_t request_sequence_id = m_request_sequence_id;
MakeRequestPacketHeader (command, request_packet, command_length);
request_packet.PutRawBytes(src, src_len);
- if (SendRequestAndGetReply (command, request_sequence_id, request_packet, reply_packet))
+ if (SendRequestAndGetReply (command, request_packet, reply_packet))
{
- uint32_t offset = 8;
+ lldb::offset_t offset = 8;
uint32_t kdp_error = reply_packet.GetU32 (&offset);
- if (kdp_error)
+ if (kdp_error && (command_byte != KDP_DUMPINFO))
error.SetErrorStringWithFormat ("request packet 0x%8.8x failed (error %u)", command_byte, kdp_error);
else
{
@@ -778,6 +780,13 @@ CommunicationKDP::GetCommandAsCString (u
case KDP_BREAKPOINT_SET64: return "KDP_BREAKPOINT64_SET";
case KDP_BREAKPOINT_REMOVE64: return "KDP_BREAKPOINT64_REMOVE";
case KDP_KERNELVERSION: return "KDP_KERNELVERSION";
+ case KDP_READPHYSMEM64: return "KDP_READPHYSMEM64";
+ case KDP_WRITEPHYSMEM64: return "KDP_WRITEPHYSMEM64";
+ case KDP_READIOPORT: return "KDP_READIOPORT";
+ case KDP_WRITEIOPORT: return "KDP_WRITEIOPORT";
+ case KDP_READMSR64: return "KDP_READMSR64";
+ case KDP_WRITEMSR64: return "KDP_WRITEMSR64";
+ case KDP_DUMPINFO: return "KDP_DUMPINFO";
}
return NULL;
}
@@ -799,7 +808,7 @@ CommunicationKDP::DumpPacket (Stream &s,
}
else
{
- uint32_t offset = 0;
+ lldb::offset_t offset = 0;
const uint8_t first_packet_byte = packet.GetU8 (&offset);
const uint8_t sequence_id = packet.GetU8 (&offset);
const uint16_t length = packet.GetU16 (&offset);
@@ -833,6 +842,8 @@ CommunicationKDP::DumpPacket (Stream &s,
case KDP_BREAKPOINT_REMOVE64:
case KDP_WRITEREGS:
case KDP_LOAD:
+ case KDP_WRITEIOPORT:
+ case KDP_WRITEMSR64:
{
const uint32_t error = packet.GetU32 (&offset);
s.Printf(" (error=0x%8.8x)", error);
@@ -883,6 +894,7 @@ CommunicationKDP::DumpPacket (Stream &s,
case KDP_READMEM:
case KDP_READMEM64:
+ case KDP_READPHYSMEM64:
{
const uint32_t error = packet.GetU32 (&offset);
const uint32_t count = packet.GetByteSize() - offset;
@@ -935,6 +947,41 @@ CommunicationKDP::DumpPacket (Stream &s,
s.Printf(" (path = \"%s\")", path);
}
break;
+
+ case KDP_READIOPORT:
+ case KDP_READMSR64:
+ {
+ const uint32_t error = packet.GetU32 (&offset);
+ const uint32_t count = packet.GetByteSize() - offset;
+ s.Printf(" (error = 0x%8.8x io:\n", error);
+ if (count > 0)
+ packet.Dump (&s, // Stream to dump to
+ offset, // Offset within "packet"
+ eFormatHex, // Format to use
+ 1, // Size of each item in bytes
+ count, // Number of items
+ 16, // Number per line
+ LLDB_INVALID_ADDRESS, // Don't show addresses before each line
+ 0, 0); // No bitfields
+ }
+ break;
+ case KDP_DUMPINFO:
+ {
+ const uint32_t count = packet.GetByteSize() - offset;
+ s.Printf(" (count = %u, bytes = \n", count);
+ if (count > 0)
+ packet.Dump (&s, // Stream to dump to
+ offset, // Offset within "packet"
+ eFormatHex, // Format to use
+ 1, // Size of each item in bytes
+ count, // Number of items
+ 16, // Number per line
+ LLDB_INVALID_ADDRESS, // Don't show addresses before each line
+ 0, 0); // No bitfields
+
+ }
+ break;
+
default:
s.Printf(" (add support for dumping this packet reply!!!");
break;
@@ -1002,6 +1049,16 @@ CommunicationKDP::DumpPacket (Stream &s,
}
break;
+ case KDP_READPHYSMEM64:
+ {
+ const uint64_t addr = packet.GetU64 (&offset);
+ const uint32_t size = packet.GetU32 (&offset);
+ const uint32_t lcpu = packet.GetU16 (&offset);
+ s.Printf(" (addr = 0x%16.16llx, size = %u, lcpu = %u)", addr, size, lcpu);
+ m_last_read_memory_addr = addr;
+ }
+ break;
+
case KDP_WRITEMEM64:
{
const uint64_t addr = packet.GetU64 (&offset);
@@ -1012,6 +1069,17 @@ CommunicationKDP::DumpPacket (Stream &s,
}
break;
+ case KDP_WRITEPHYSMEM64:
+ {
+ const uint64_t addr = packet.GetU64 (&offset);
+ const uint32_t size = packet.GetU32 (&offset);
+ const uint32_t lcpu = packet.GetU16 (&offset);
+ s.Printf(" (addr = 0x%16.16llx, size = %u, lcpu = %u, bytes = \n", addr, size, lcpu);
+ if (size > 0)
+ DataExtractor::DumpHexBytes(&s, packet.GetData(&offset, size), size, 32, addr);
+ }
+ break;
+
case KDP_READREGS:
{
const uint32_t cpu = packet.GetU32 (&offset);
@@ -1110,7 +1178,78 @@ CommunicationKDP::DumpPacket (Stream &s,
s.Printf(" (reply_port = %u)", reply_port);
}
break;
- }
+
+ case KDP_READMSR64:
+ {
+ const uint32_t address = packet.GetU32 (&offset);
+ const uint16_t lcpu = packet.GetU16 (&offset);
+ s.Printf(" (address=0x%8.8x, lcpu=0x%4.4x)", address, lcpu);
+ }
+ break;
+
+ case KDP_WRITEMSR64:
+ {
+ const uint32_t address = packet.GetU32 (&offset);
+ const uint16_t lcpu = packet.GetU16 (&offset);
+ const uint32_t nbytes = packet.GetByteSize() - offset;
+ s.Printf(" (address=0x%8.8x, lcpu=0x%4.4x, nbytes=0x%8.8x)", lcpu, address, nbytes);
+ if (nbytes > 0)
+ packet.Dump (&s, // Stream to dump to
+ offset, // Offset within "packet"
+ eFormatHex, // Format to use
+ 1, // Size of each item in bytes
+ nbytes, // Number of items
+ 16, // Number per line
+ LLDB_INVALID_ADDRESS, // Don't show addresses before each line
+ 0, 0); // No bitfields
+ }
+ break;
+
+ case KDP_READIOPORT:
+ {
+ const uint16_t lcpu = packet.GetU16 (&offset);
+ const uint16_t address = packet.GetU16 (&offset);
+ const uint16_t nbytes = packet.GetU16 (&offset);
+ s.Printf(" (lcpu=0x%4.4x, address=0x%4.4x, nbytes=%u)", lcpu, address, nbytes);
+ }
+ break;
+
+ case KDP_WRITEIOPORT:
+ {
+ const uint16_t lcpu = packet.GetU16 (&offset);
+ const uint16_t address = packet.GetU16 (&offset);
+ const uint16_t nbytes = packet.GetU16 (&offset);
+ s.Printf(" (lcpu = %u, addr = 0x%4.4x, nbytes = %u, bytes = \n", lcpu, address, nbytes);
+ if (nbytes > 0)
+ packet.Dump (&s, // Stream to dump to
+ offset, // Offset within "packet"
+ eFormatHex, // Format to use
+ 1, // Size of each item in bytes
+ nbytes, // Number of items
+ 16, // Number per line
+ LLDB_INVALID_ADDRESS, // Don't show addresses before each line
+ 0, 0); // No bitfields
+ }
+ break;
+
+ case KDP_DUMPINFO:
+ {
+ const uint32_t count = packet.GetByteSize() - offset;
+ s.Printf(" (count = %u, bytes = \n", count);
+ if (count > 0)
+ packet.Dump (&s, // Stream to dump to
+ offset, // Offset within "packet"
+ eFormatHex, // Format to use
+ 1, // Size of each item in bytes
+ count, // Number of items
+ 16, // Number per line
+ LLDB_INVALID_ADDRESS, // Don't show addresses before each line
+ 0, 0); // No bitfields
+
+ }
+ break;
+
+ }
}
}
else
@@ -1145,14 +1284,13 @@ CommunicationKDP::SendRequestReadRegiste
const CommandType command = KDP_READREGS;
// Size is header + 4 byte cpu and 4 byte flavor
const uint32_t command_length = 8 + 4 + 4;
- const uint32_t request_sequence_id = m_request_sequence_id;
MakeRequestPacketHeader (command, request_packet, command_length);
request_packet.PutHex32 (cpu);
request_packet.PutHex32 (flavor);
DataExtractor reply_packet;
- if (SendRequestAndGetReply (command, request_sequence_id, request_packet, reply_packet))
+ if (SendRequestAndGetReply (command, request_packet, reply_packet))
{
- uint32_t offset = 8;
+ lldb::offset_t offset = 8;
uint32_t kdp_error = reply_packet.GetU32 (&offset);
uint32_t src_len = reply_packet.GetByteSize() - 12;
@@ -1192,15 +1330,14 @@ CommunicationKDP::SendRequestWriteRegist
const CommandType command = KDP_WRITEREGS;
// Size is header + 4 byte cpu and 4 byte flavor
const uint32_t command_length = 8 + 4 + 4 + src_len;
- const uint32_t request_sequence_id = m_request_sequence_id;
MakeRequestPacketHeader (command, request_packet, command_length);
request_packet.PutHex32 (cpu);
request_packet.PutHex32 (flavor);
request_packet.Write(src, src_len);
DataExtractor reply_packet;
- if (SendRequestAndGetReply (command, request_sequence_id, request_packet, reply_packet))
+ if (SendRequestAndGetReply (command, request_packet, reply_packet))
{
- uint32_t offset = 8;
+ lldb::offset_t offset = 8;
uint32_t kdp_error = reply_packet.GetU32 (&offset);
if (kdp_error == 0)
return src_len;
@@ -1220,12 +1357,11 @@ CommunicationKDP::SendRequestResume ()
PacketStreamType request_packet (Stream::eBinary, m_addr_byte_size, m_byte_order);
const CommandType command = KDP_RESUMECPUS;
const uint32_t command_length = 12;
- const uint32_t request_sequence_id = m_request_sequence_id;
MakeRequestPacketHeader (command, request_packet, command_length);
request_packet.PutHex32(GetCPUMask());
DataExtractor reply_packet;
- if (SendRequestAndGetReply (command, request_sequence_id, request_packet, reply_packet))
+ if (SendRequestAndGetReply (command, request_packet, reply_packet))
return true;
return false;
}
@@ -1240,14 +1376,13 @@ CommunicationKDP::SendRequestBreakpoint
(use_64 ? KDP_BREAKPOINT_REMOVE64 : KDP_BREAKPOINT_REMOVE);
const uint32_t command_length = 8 + command_addr_byte_size;
- const uint32_t request_sequence_id = m_request_sequence_id;
MakeRequestPacketHeader (command, request_packet, command_length);
request_packet.PutMaxHex64 (addr, command_addr_byte_size);
DataExtractor reply_packet;
- if (SendRequestAndGetReply (command, request_sequence_id, request_packet, reply_packet))
+ if (SendRequestAndGetReply (command, request_packet, reply_packet))
{
- uint32_t offset = 8;
+ lldb::offset_t offset = 8;
uint32_t kdp_error = reply_packet.GetU32 (&offset);
if (kdp_error == 0)
return true;
@@ -1261,10 +1396,9 @@ CommunicationKDP::SendRequestSuspend ()
PacketStreamType request_packet (Stream::eBinary, m_addr_byte_size, m_byte_order);
const CommandType command = KDP_SUSPEND;
const uint32_t command_length = 8;
- const uint32_t request_sequence_id = m_request_sequence_id;
MakeRequestPacketHeader (command, request_packet, command_length);
DataExtractor reply_packet;
- if (SendRequestAndGetReply (command, request_sequence_id, request_packet, reply_packet))
+ if (SendRequestAndGetReply (command, request_packet, reply_packet))
return true;
return false;
}
Modified: lldb/branches/windows/source/Plugins/Process/MacOSX-Kernel/CommunicationKDP.h
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/windows/source/Plugins/Process/MacOSX-Kernel/CommunicationKDP.h?rev=179679&r1=179678&r2=179679&view=diff
==============================================================================
--- lldb/branches/windows/source/Plugins/Process/MacOSX-Kernel/CommunicationKDP.h (original)
+++ lldb/branches/windows/source/Plugins/Process/MacOSX-Kernel/CommunicationKDP.h Wed Apr 17 03:38:48 2013
@@ -62,7 +62,14 @@ public:
KDP_WRITEMEM64,
KDP_BREAKPOINT_SET64,
KDP_BREAKPOINT_REMOVE64,
- KDP_KERNELVERSION
+ KDP_KERNELVERSION,
+ KDP_READPHYSMEM64,
+ KDP_WRITEPHYSMEM64,
+ KDP_READIOPORT,
+ KDP_WRITEIOPORT,
+ KDP_READMSR64,
+ KDP_WRITEMSR64,
+ KDP_DUMPINFO
} CommandType;
enum
@@ -315,7 +322,6 @@ protected:
bool
SendRequestAndGetReply (const CommandType command,
- const uint8_t request_sequence_id,
const PacketStreamType &request_packet,
lldb_private::DataExtractor &reply_packet);
//------------------------------------------------------------------
Modified: lldb/branches/windows/source/Plugins/Process/MacOSX-Kernel/ProcessKDP.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/windows/source/Plugins/Process/MacOSX-Kernel/ProcessKDP.cpp?rev=179679&r1=179678&r2=179679&view=diff
==============================================================================
--- lldb/branches/windows/source/Plugins/Process/MacOSX-Kernel/ProcessKDP.cpp (original)
+++ lldb/branches/windows/source/Plugins/Process/MacOSX-Kernel/ProcessKDP.cpp Wed Apr 17 03:38:48 2013
@@ -114,7 +114,6 @@ ProcessKDP::ProcessKDP(Target& target, L
m_comm("lldb.process.kdp-remote.communication"),
m_async_broadcaster (NULL, "lldb.process.kdp-remote.async-broadcaster"),
m_async_thread (LLDB_INVALID_HOST_THREAD),
- m_destroy_in_process (false),
m_dyld_plugin_name (),
m_kernel_load_addr (LLDB_INVALID_ADDRESS),
m_command_sp()
@@ -334,7 +333,7 @@ ProcessKDP::DoAttachToProcessWithName (c
void
ProcessKDP::DidAttach ()
{
- LogSP log (ProcessKDPLog::GetLogIfAllCategoriesSet (KDP_LOG_PROCESS));
+ Log *log (ProcessKDPLog::GetLogIfAllCategoriesSet (KDP_LOG_PROCESS));
if (log)
log->Printf ("ProcessKDP::DidAttach()");
if (GetID() != LLDB_INVALID_PROCESS_ID)
@@ -367,7 +366,7 @@ Error
ProcessKDP::DoResume ()
{
Error error;
- LogSP log (ProcessKDPLog::GetLogIfAllCategoriesSet (KDP_LOG_PROCESS));
+ Log *log (ProcessKDPLog::GetLogIfAllCategoriesSet (KDP_LOG_PROCESS));
// Only start the async thread if we try to do any process control
if (!IS_VALID_LLDB_HOST_THREAD(m_async_thread))
StartAsyncThread ();
@@ -387,13 +386,35 @@ ProcessKDP::DoResume ()
break;
case eStateStepping:
- kernel_thread_sp->GetRegisterContext()->HardwareSingleStep (true);
- resume = true;
+ {
+ lldb::RegisterContextSP reg_ctx_sp (kernel_thread_sp->GetRegisterContext());
+
+ if (reg_ctx_sp)
+ {
+ reg_ctx_sp->HardwareSingleStep (true);
+ resume = true;
+ }
+ else
+ {
+ error.SetErrorStringWithFormat("KDP thread 0x%llx has no register context", kernel_thread_sp->GetID());
+ }
+ }
break;
case eStateRunning:
- kernel_thread_sp->GetRegisterContext()->HardwareSingleStep (false);
- resume = true;
+ {
+ lldb::RegisterContextSP reg_ctx_sp (kernel_thread_sp->GetRegisterContext());
+
+ if (reg_ctx_sp)
+ {
+ reg_ctx_sp->HardwareSingleStep (false);
+ resume = true;
+ }
+ else
+ {
+ error.SetErrorStringWithFormat("KDP thread 0x%llx has no register context", kernel_thread_sp->GetID());
+ }
+ }
break;
default:
@@ -432,10 +453,8 @@ ProcessKDP::GetKernelThread(ThreadList &
const lldb::tid_t kernel_tid = 1;
ThreadSP thread_sp (old_thread_list.FindThreadByID (kernel_tid, false));
if (!thread_sp)
- {
thread_sp.reset(new ThreadKDP (*this, kernel_tid));
- new_thread_list.AddThread(thread_sp);
- }
+ new_thread_list.AddThread(thread_sp);
return thread_sp;
}
@@ -446,11 +465,11 @@ bool
ProcessKDP::UpdateThreadList (ThreadList &old_thread_list, ThreadList &new_thread_list)
{
// locker will keep a mutex locked until it goes out of scope
- LogSP log (ProcessKDPLog::GetLogIfAllCategoriesSet (KDP_LOG_THREAD));
+ Log *log (ProcessKDPLog::GetLogIfAllCategoriesSet (KDP_LOG_THREAD));
if (log && log->GetMask().Test(KDP_LOG_VERBOSE))
log->Printf ("ProcessKDP::%s (pid = %" PRIu64 ")", __FUNCTION__, GetID());
- // Even though there is a CPU mask, it doesn't mean to can see each CPU
+ // Even though there is a CPU mask, it doesn't mean we can see each CPU
// indivudually, there is really only one. Lets call this thread 1.
GetKernelThread (old_thread_list, new_thread_list);
@@ -491,7 +510,7 @@ Error
ProcessKDP::DoDetach()
{
Error error;
- LogSP log (ProcessKDPLog::GetLogIfAllCategoriesSet(KDP_LOG_PROCESS));
+ Log *log (ProcessKDPLog::GetLogIfAllCategoriesSet(KDP_LOG_PROCESS));
if (log)
log->Printf ("ProcessKDP::DoDetach()");
@@ -532,14 +551,6 @@ ProcessKDP::DoDetach()
}
Error
-ProcessKDP::WillDestroy ()
-{
- Error error;
- m_destroy_in_process = true;
- return error;
-}
-
-Error
ProcessKDP::DoDestroy ()
{
// For KDP there really is no difference between destroy and detach
@@ -593,7 +604,7 @@ ProcessKDP::DoDeallocateMemory (lldb::ad
}
Error
-ProcessKDP::EnableBreakpoint (BreakpointSite *bp_site)
+ProcessKDP::EnableBreakpointSite (BreakpointSite *bp_site)
{
if (m_comm.LocalBreakpointsAreSupported ())
{
@@ -616,7 +627,7 @@ ProcessKDP::EnableBreakpoint (Breakpoint
}
Error
-ProcessKDP::DisableBreakpoint (BreakpointSite *bp_site)
+ProcessKDP::DisableBreakpointSite (BreakpointSite *bp_site)
{
if (m_comm.LocalBreakpointsAreSupported ())
{
@@ -704,7 +715,7 @@ ProcessKDP::Initialize()
bool
ProcessKDP::StartAsyncThread ()
{
- LogSP log (ProcessKDPLog::GetLogIfAllCategoriesSet(KDP_LOG_PROCESS));
+ Log *log (ProcessKDPLog::GetLogIfAllCategoriesSet(KDP_LOG_PROCESS));
if (log)
log->Printf ("ProcessKDP::StartAsyncThread ()");
@@ -719,7 +730,7 @@ ProcessKDP::StartAsyncThread ()
void
ProcessKDP::StopAsyncThread ()
{
- LogSP log (ProcessKDPLog::GetLogIfAllCategoriesSet(KDP_LOG_PROCESS));
+ Log *log (ProcessKDPLog::GetLogIfAllCategoriesSet(KDP_LOG_PROCESS));
if (log)
log->Printf ("ProcessKDP::StopAsyncThread ()");
@@ -742,7 +753,7 @@ ProcessKDP::AsyncThread (void *arg)
const lldb::pid_t pid = process->GetID();
- LogSP log (ProcessKDPLog::GetLogIfAllCategoriesSet (KDP_LOG_PROCESS));
+ Log *log (ProcessKDPLog::GetLogIfAllCategoriesSet (KDP_LOG_PROCESS));
if (log)
log->Printf ("ProcessKDP::AsyncThread (arg = %p, pid = %" PRIu64 ") thread starting...", arg, pid);
@@ -783,8 +794,13 @@ ProcessKDP::AsyncThread (void *arg)
if (process->m_comm.WaitForPacketWithTimeoutMicroSeconds (exc_reply_packet, 1 * USEC_PER_SEC))
{
ThreadSP thread_sp (process->GetKernelThread(process->GetThreadList(), process->GetThreadList()));
- thread_sp->GetRegisterContext()->InvalidateAllRegisters();
- static_cast<ThreadKDP *>(thread_sp.get())->SetStopInfoFrom_KDP_EXCEPTION (exc_reply_packet);
+ if (thread_sp)
+ {
+ lldb::RegisterContextSP reg_ctx_sp (thread_sp->GetRegisterContext());
+ if (reg_ctx_sp)
+ reg_ctx_sp->InvalidateAllRegisters();
+ static_cast<ThreadKDP *>(thread_sp.get())->SetStopInfoFrom_KDP_EXCEPTION (exc_reply_packet);
+ }
// TODO: parse the stop reply packet
is_running = false;
Modified: lldb/branches/windows/source/Plugins/Process/MacOSX-Kernel/ProcessKDP.h
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/windows/source/Plugins/Process/MacOSX-Kernel/ProcessKDP.h?rev=179679&r1=179678&r2=179679&view=diff
==============================================================================
--- lldb/branches/windows/source/Plugins/Process/MacOSX-Kernel/ProcessKDP.h (original)
+++ lldb/branches/windows/source/Plugins/Process/MacOSX-Kernel/ProcessKDP.h Wed Apr 17 03:38:48 2013
@@ -141,9 +141,6 @@ public:
DoSignal (int signal);
virtual lldb_private::Error
- WillDestroy ();
-
- virtual lldb_private::Error
DoDestroy ();
virtual void
@@ -174,10 +171,10 @@ public:
// Process Breakpoints
//----------------------------------------------------------------------
virtual lldb_private::Error
- EnableBreakpoint (lldb_private::BreakpointSite *bp_site);
+ EnableBreakpointSite (lldb_private::BreakpointSite *bp_site);
virtual lldb_private::Error
- DisableBreakpoint (lldb_private::BreakpointSite *bp_site);
+ DisableBreakpointSite (lldb_private::BreakpointSite *bp_site);
//----------------------------------------------------------------------
// Process Watchpoints
@@ -257,7 +254,6 @@ protected:
CommunicationKDP m_comm;
lldb_private::Broadcaster m_async_broadcaster;
lldb::thread_t m_async_thread;
- bool m_destroy_in_process;
std::string m_dyld_plugin_name;
lldb::addr_t m_kernel_load_addr;
lldb::CommandObjectSP m_command_sp;
Modified: lldb/branches/windows/source/Plugins/Process/MacOSX-Kernel/ProcessKDPLog.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/windows/source/Plugins/Process/MacOSX-Kernel/ProcessKDPLog.cpp?rev=179679&r1=179678&r2=179679&view=diff
==============================================================================
--- lldb/branches/windows/source/Plugins/Process/MacOSX-Kernel/ProcessKDPLog.cpp (original)
+++ lldb/branches/windows/source/Plugins/Process/MacOSX-Kernel/ProcessKDPLog.cpp Wed Apr 17 03:38:48 2013
@@ -20,24 +20,27 @@ using namespace lldb_private;
// We want to avoid global constructors where code needs to be run so here we
// control access to our static g_log_sp by hiding it in a singleton function
-// that will construct the static g_lob_sp the first time this function is
+// that will construct the static g_log_sp the first time this function is
// called.
-static LogSP &
+static bool g_log_enabled = false;
+static Log * g_log = NULL;
+static Log *
GetLog ()
{
- static LogSP g_log_sp;
- return g_log_sp;
+ if (!g_log_enabled)
+ return NULL;
+ return g_log;
}
-LogSP
+Log *
ProcessKDPLog::GetLogIfAllCategoriesSet (uint32_t mask)
{
- LogSP log(GetLog ());
+ Log *log(GetLog ());
if (log && mask)
{
uint32_t log_mask = log->GetMask().Get();
if ((log_mask & mask) != mask)
- return LogSP();
+ return NULL;
}
return log;
}
@@ -45,7 +48,7 @@ ProcessKDPLog::GetLogIfAllCategoriesSet
void
ProcessKDPLog::DisableLog (const char **categories, Stream *feedback_strm)
{
- LogSP log (GetLog ());
+ Log *log (GetLog ());
if (log)
{
uint32_t flag_bits = 0;
@@ -81,33 +84,33 @@ ProcessKDPLog::DisableLog (const char **
}
}
+ log->GetMask().Reset (flag_bits);
if (flag_bits == 0)
- GetLog ().reset();
- else
- log->GetMask().Reset (flag_bits);
+ g_log_enabled = false;
}
return;
}
-LogSP
+Log *
ProcessKDPLog::EnableLog (StreamSP &log_stream_sp, uint32_t log_options, const char **categories, Stream *feedback_strm)
{
// Try see if there already is a log - that way we can reuse its settings.
// We could reuse the log in toto, but we don't know that the stream is the same.
uint32_t flag_bits = 0;
- LogSP log(GetLog ());
- if (log)
- flag_bits = log->GetMask().Get();
+ if (g_log)
+ flag_bits = g_log->GetMask().Get();
// Now make a new log with this stream if one was provided
if (log_stream_sp)
{
- log.reset (new Log(log_stream_sp));
- GetLog () = log;
+ if (g_log)
+ g_log->SetStream(log_stream_sp);
+ else
+ g_log = new Log(log_stream_sp);
}
- if (log)
+ if (g_log)
{
bool got_unknown_category = false;
for (size_t i=0; categories[i] != NULL; ++i)
@@ -140,10 +143,11 @@ ProcessKDPLog::EnableLog (StreamSP &log_
}
if (flag_bits == 0)
flag_bits = KDP_LOG_DEFAULT;
- log->GetMask().Reset(flag_bits);
- log->GetOptions().Reset(log_options);
+ g_log->GetMask().Reset(flag_bits);
+ g_log->GetOptions().Reset(log_options);
}
- return log;
+ g_log_enabled = true;
+ return g_log;
}
void
@@ -170,7 +174,7 @@ ProcessKDPLog::ListLogCategories (Stream
void
ProcessKDPLog::LogIf (uint32_t mask, const char *format, ...)
{
- LogSP log (ProcessKDPLog::GetLogIfAllCategoriesSet (mask));
+ Log *log (ProcessKDPLog::GetLogIfAllCategoriesSet (mask));
if (log)
{
va_list args;
Modified: lldb/branches/windows/source/Plugins/Process/MacOSX-Kernel/ProcessKDPLog.h
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/windows/source/Plugins/Process/MacOSX-Kernel/ProcessKDPLog.h?rev=179679&r1=179678&r2=179679&view=diff
==============================================================================
--- lldb/branches/windows/source/Plugins/Process/MacOSX-Kernel/ProcessKDPLog.h (original)
+++ lldb/branches/windows/source/Plugins/Process/MacOSX-Kernel/ProcessKDPLog.h Wed Apr 17 03:38:48 2013
@@ -35,13 +35,13 @@
class ProcessKDPLog
{
public:
- static lldb::LogSP
+ static lldb_private::Log *
GetLogIfAllCategoriesSet(uint32_t mask = 0);
static void
DisableLog (const char **categories, lldb_private::Stream *feedback_strm);
- static lldb::LogSP
+ static lldb_private::Log *
EnableLog (lldb::StreamSP &log_stream_sp, uint32_t log_options, const char **categories, lldb_private::Stream *feedback_strm);
static void
Modified: lldb/branches/windows/source/Plugins/Process/MacOSX-Kernel/ThreadKDP.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/windows/source/Plugins/Process/MacOSX-Kernel/ThreadKDP.cpp?rev=179679&r1=179678&r2=179679&view=diff
==============================================================================
--- lldb/branches/windows/source/Plugins/Process/MacOSX-Kernel/ThreadKDP.cpp (original)
+++ lldb/branches/windows/source/Plugins/Process/MacOSX-Kernel/ThreadKDP.cpp Wed Apr 17 03:38:48 2013
@@ -76,7 +76,7 @@ ThreadKDP::WillResume (StateType resume_
ClearStackFrames();
- lldb::LogSP log(lldb_private::GetLogIfAnyCategoriesSet (LIBLLDB_LOG_STEP));
+ Log *log(lldb_private::GetLogIfAnyCategoriesSet (LIBLLDB_LOG_STEP));
if (log)
log->Printf ("Resuming thread: %4.4" PRIx64 " with state: %s.", GetID(), StateAsCString(resume_state));
@@ -95,7 +95,9 @@ ThreadKDP::RefreshStateAfterStop()
// register supply functions where they check the process stop ID and do
// the right thing.
const bool force = false;
- GetRegisterContext()->InvalidateIfNeeded (force);
+ lldb::RegisterContextSP reg_ctx_sp (GetRegisterContext());
+ if (reg_ctx_sp)
+ reg_ctx_sp->InvalidateIfNeeded (force);
}
void
@@ -164,8 +166,12 @@ ThreadKDP::CreateRegisterContextForFrame
}
}
}
- else if (m_unwinder_ap.get())
- reg_ctx_sp = m_unwinder_ap->CreateRegisterContextForFrame (frame);
+ else
+ {
+ Unwind *unwinder = GetUnwinder ();
+ if (unwinder)
+ reg_ctx_sp = unwinder->CreateRegisterContextForFrame (frame);
+ }
return reg_ctx_sp;
}
@@ -194,7 +200,7 @@ ThreadKDP::GetPrivateStopReason ()
void
ThreadKDP::SetStopInfoFrom_KDP_EXCEPTION (const DataExtractor &exc_reply_packet)
{
- uint32_t offset = 0;
+ lldb::offset_t offset = 0;
uint8_t reply_command = exc_reply_packet.GetU8(&offset);
if (reply_command == CommunicationKDP::KDP_EXCEPTION)
{
Modified: lldb/branches/windows/source/Plugins/Process/POSIX/POSIXStopInfo.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/windows/source/Plugins/Process/POSIX/POSIXStopInfo.cpp?rev=179679&r1=179678&r2=179679&view=diff
==============================================================================
--- lldb/branches/windows/source/Plugins/Process/POSIX/POSIXStopInfo.cpp (original)
+++ lldb/branches/windows/source/Plugins/Process/POSIX/POSIXStopInfo.cpp Wed Apr 17 03:38:48 2013
@@ -58,3 +58,32 @@ POSIXCrashStopInfo::GetDescription()
{
return ProcessMessage::GetCrashReasonString(m_crash_reason);
}
+
+//===----------------------------------------------------------------------===//
+// POSIXNewThreadStopInfo
+
+POSIXNewThreadStopInfo::~POSIXNewThreadStopInfo() { }
+
+lldb::StopReason
+POSIXNewThreadStopInfo::GetStopReason() const
+{
+ return lldb::eStopReasonNone;
+}
+
+const char *
+POSIXNewThreadStopInfo::GetDescription()
+{
+ return "thread spawned";
+}
+
+bool
+POSIXNewThreadStopInfo::ShouldStop(Event *event_ptr)
+{
+ return false;
+}
+
+bool
+POSIXNewThreadStopInfo::ShouldNotify(Event *event_ptr)
+{
+ return false;
+}
Modified: lldb/branches/windows/source/Plugins/Process/POSIX/POSIXStopInfo.h
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/windows/source/Plugins/Process/POSIX/POSIXStopInfo.h?rev=179679&r1=179678&r2=179679&view=diff
==============================================================================
--- lldb/branches/windows/source/Plugins/Process/POSIX/POSIXStopInfo.h (original)
+++ lldb/branches/windows/source/Plugins/Process/POSIX/POSIXStopInfo.h Wed Apr 17 03:38:48 2013
@@ -89,4 +89,32 @@ private:
ProcessMessage::CrashReason m_crash_reason;
};
+//===----------------------------------------------------------------------===//
+/// @class POSIXNewThreadStopInfo
+/// @brief Represents the stop state of process when a new thread is spawned.
+///
+
+class POSIXNewThreadStopInfo
+ : public POSIXStopInfo
+{
+public:
+ POSIXNewThreadStopInfo (POSIXThread &thread)
+ : POSIXStopInfo (thread, 0)
+ { }
+
+ ~POSIXNewThreadStopInfo();
+
+ lldb::StopReason
+ GetStopReason() const;
+
+ const char *
+ GetDescription();
+
+ bool
+ ShouldStop(lldb_private::Event *event_ptr);
+
+ bool
+ ShouldNotify(lldb_private::Event *event_ptr);
+};
+
#endif
Modified: lldb/branches/windows/source/Plugins/Process/POSIX/POSIXThread.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/windows/source/Plugins/Process/POSIX/POSIXThread.cpp?rev=179679&r1=179678&r2=179679&view=diff
==============================================================================
--- lldb/branches/windows/source/Plugins/Process/POSIX/POSIXThread.cpp (original)
+++ lldb/branches/windows/source/Plugins/Process/POSIX/POSIXThread.cpp Wed Apr 17 03:38:48 2013
@@ -39,7 +39,7 @@ POSIXThread::POSIXThread(Process &proces
: Thread(process, tid),
m_frame_ap(0)
{
- LogSP log (ProcessPOSIXLog::GetLogIfAllCategoriesSet (POSIX_LOG_THREAD));
+ Log *log (ProcessPOSIXLog::GetLogIfAllCategoriesSet (POSIX_LOG_THREAD));
if (log && log->GetMask().Test(POSIX_LOG_VERBOSE))
log->Printf ("POSIXThread::%s (tid = %" PRIi64 ")", __FUNCTION__, tid);
}
@@ -60,7 +60,7 @@ POSIXThread::GetMonitor()
void
POSIXThread::RefreshStateAfterStop()
{
- LogSP log (ProcessPOSIXLog::GetLogIfAllCategoriesSet (POSIX_LOG_THREAD));
+ Log *log (ProcessPOSIXLog::GetLogIfAllCategoriesSet (POSIX_LOG_THREAD));
if (log && log->GetMask().Test(POSIX_LOG_VERBOSE))
log->Printf ("POSIXThread::%s ()", __FUNCTION__);
@@ -110,7 +110,7 @@ POSIXThread::CreateRegisterContextForFra
lldb::RegisterContextSP reg_ctx_sp;
uint32_t concrete_frame_idx = 0;
- LogSP log (ProcessPOSIXLog::GetLogIfAllCategoriesSet (POSIX_LOG_THREAD));
+ Log *log (ProcessPOSIXLog::GetLogIfAllCategoriesSet (POSIX_LOG_THREAD));
if (log && log->GetMask().Test(POSIX_LOG_VERBOSE))
log->Printf ("POSIXThread::%s ()", __FUNCTION__);
@@ -165,7 +165,7 @@ POSIXThread::Resume()
ProcessMonitor &monitor = GetMonitor();
bool status;
- LogSP log (ProcessPOSIXLog::GetLogIfAllCategoriesSet (POSIX_LOG_THREAD));
+ Log *log (ProcessPOSIXLog::GetLogIfAllCategoriesSet (POSIX_LOG_THREAD));
if (log && log->GetMask().Test(POSIX_LOG_VERBOSE))
log->Printf ("POSIXThread::%s ()", __FUNCTION__);
@@ -185,6 +185,10 @@ POSIXThread::Resume()
SetState(resume_state);
status = monitor.SingleStep(GetID(), GetResumeSignal());
break;
+ case lldb::eStateStopped:
+ case lldb::eStateSuspended:
+ status = true;
+ break;
}
return status;
@@ -193,7 +197,7 @@ POSIXThread::Resume()
void
POSIXThread::Notify(const ProcessMessage &message)
{
- LogSP log (ProcessPOSIXLog::GetLogIfAllCategoriesSet (POSIX_LOG_THREAD));
+ Log *log (ProcessPOSIXLog::GetLogIfAllCategoriesSet (POSIX_LOG_THREAD));
if (log)
log->Printf ("POSIXThread::%s () message kind = '%s'", __FUNCTION__, message.PrintKind());
@@ -226,6 +230,10 @@ POSIXThread::Notify(const ProcessMessage
case ProcessMessage::eCrashMessage:
CrashNotify(message);
break;
+
+ case ProcessMessage::eNewThreadMessage:
+ ThreadNotify(message);
+ break;
}
}
@@ -233,7 +241,7 @@ void
POSIXThread::BreakNotify(const ProcessMessage &message)
{
bool status;
- LogSP log (ProcessPOSIXLog::GetLogIfAllCategoriesSet (POSIX_LOG_THREAD));
+ Log *log (ProcessPOSIXLog::GetLogIfAllCategoriesSet (POSIX_LOG_THREAD));
assert(GetRegisterContext());
status = GetRegisterContextPOSIX()->UpdateAfterBreakpoint();
@@ -292,7 +300,7 @@ POSIXThread::CrashNotify(const ProcessMe
assert(message.GetKind() == ProcessMessage::eCrashMessage);
- LogSP log (ProcessPOSIXLog::GetLogIfAllCategoriesSet (POSIX_LOG_THREAD));
+ Log *log (ProcessPOSIXLog::GetLogIfAllCategoriesSet (POSIX_LOG_THREAD));
if (log)
log->Printf ("POSIXThread::%s () signo = %i, reason = '%s'", __FUNCTION__, signo, message.PrintCrashReason());
@@ -301,6 +309,12 @@ POSIXThread::CrashNotify(const ProcessMe
SetResumeSignal(signo);
}
+void
+POSIXThread::ThreadNotify(const ProcessMessage &message)
+{
+ m_stop_info = lldb::StopInfoSP(new POSIXNewThreadStopInfo(*this));
+}
+
unsigned
POSIXThread::GetRegisterIndexFromOffset(unsigned offset)
{
Modified: lldb/branches/windows/source/Plugins/Process/POSIX/POSIXThread.h
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/windows/source/Plugins/Process/POSIX/POSIXThread.h?rev=179679&r1=179678&r2=179679&view=diff
==============================================================================
--- lldb/branches/windows/source/Plugins/Process/POSIX/POSIXThread.h (original)
+++ lldb/branches/windows/source/Plugins/Process/POSIX/POSIXThread.h Wed Apr 17 03:38:48 2013
@@ -98,6 +98,7 @@ private:
void SignalNotify(const ProcessMessage &message);
void SignalDeliveredNotify(const ProcessMessage &message);
void CrashNotify(const ProcessMessage &message);
+ void ThreadNotify(const ProcessMessage &message);
lldb_private::Unwind *
GetUnwinder();
Modified: lldb/branches/windows/source/Plugins/Process/POSIX/ProcessMessage.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/windows/source/Plugins/Process/POSIX/ProcessMessage.cpp?rev=179679&r1=179678&r2=179679&view=diff
==============================================================================
--- lldb/branches/windows/source/Plugins/Process/POSIX/ProcessMessage.cpp (original)
+++ lldb/branches/windows/source/Plugins/Process/POSIX/ProcessMessage.cpp Wed Apr 17 03:38:48 2013
@@ -224,6 +224,9 @@ ProcessMessage::PrintKind(Kind kind)
case eCrashMessage:
str = "eCrashMessage";
break;
+ case eNewThreadMessage:
+ str = "eNewThreadMessage";
+ break;
}
#endif
Modified: lldb/branches/windows/source/Plugins/Process/POSIX/ProcessMessage.h
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/windows/source/Plugins/Process/POSIX/ProcessMessage.h?rev=179679&r1=179678&r2=179679&view=diff
==============================================================================
--- lldb/branches/windows/source/Plugins/Process/POSIX/ProcessMessage.h (original)
+++ lldb/branches/windows/source/Plugins/Process/POSIX/ProcessMessage.h Wed Apr 17 03:38:48 2013
@@ -29,7 +29,8 @@ public:
eSignalDeliveredMessage,
eTraceMessage,
eBreakpointMessage,
- eCrashMessage
+ eCrashMessage,
+ eNewThreadMessage
};
enum CrashReason
@@ -111,6 +112,11 @@ public:
return message;
}
+ /// Indicates that the thread @p tid was spawned.
+ static ProcessMessage NewThread(lldb::tid_t parent_tid, lldb::tid_t child_tid) {
+ return ProcessMessage(parent_tid, eNewThreadMessage, child_tid);
+ }
+
int GetExitStatus() const {
assert(GetKind() == eExitMessage || GetKind() == eLimboMessage);
return m_status;
@@ -137,6 +143,11 @@ public:
return m_addr;
}
+ lldb::tid_t GetChildTID() const {
+ assert(GetKind() == eNewThreadMessage);
+ return m_child_tid;
+ }
+
static const char *
GetCrashReasonString(CrashReason reason);
@@ -159,13 +170,23 @@ private:
m_kind(kind),
m_crash_reason(eInvalidCrashReason),
m_status(status),
- m_addr(addr) { }
+ m_addr(addr),
+ m_child_tid(0) { }
+
+ ProcessMessage(lldb::tid_t tid, Kind kind, lldb::tid_t child_tid)
+ : m_tid(tid),
+ m_kind(kind),
+ m_crash_reason(eInvalidCrashReason),
+ m_status(0),
+ m_addr(0),
+ m_child_tid(child_tid) { }
lldb::tid_t m_tid;
Kind m_kind : 8;
CrashReason m_crash_reason : 8;
int m_status;
lldb::addr_t m_addr;
+ lldb::tid_t m_child_tid;
};
#endif // #ifndef liblldb_ProcessMessage_H_
Modified: lldb/branches/windows/source/Plugins/Process/POSIX/ProcessPOSIX.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/windows/source/Plugins/Process/POSIX/ProcessPOSIX.cpp?rev=179679&r1=179678&r2=179679&view=diff
==============================================================================
--- lldb/branches/windows/source/Plugins/Process/POSIX/ProcessPOSIX.cpp (original)
+++ lldb/branches/windows/source/Plugins/Process/POSIX/ProcessPOSIX.cpp Wed Apr 17 03:38:48 2013
@@ -17,6 +17,7 @@
#include "lldb/Core/Module.h"
#include "lldb/Core/PluginManager.h"
#include "lldb/Core/State.h"
+#include "lldb/Host/FileSpec.h"
#include "lldb/Host/Host.h"
#include "lldb/Symbol/ObjectFile.h"
#include "lldb/Target/DynamicLoader.h"
@@ -106,7 +107,7 @@ ProcessPOSIX::DoAttachToProcessWithID(ll
Error error;
assert(m_monitor == NULL);
- LogSP log (ProcessPOSIXLog::GetLogIfAllCategoriesSet (POSIX_LOG_PROCESS));
+ Log *log (ProcessPOSIXLog::GetLogIfAllCategoriesSet (POSIX_LOG_PROCESS));
if (log && log->GetMask().Test(POSIX_LOG_VERBOSE))
log->Printf ("ProcessPOSIX::%s(pid = %" PRIi64 ")", __FUNCTION__, GetID());
@@ -162,6 +163,16 @@ ProcessPOSIX::DoLaunch (Module *module,
Error error;
assert(m_monitor == NULL);
+ const char* working_dir = launch_info.GetWorkingDirectory();
+ if (working_dir) {
+ FileSpec WorkingDir(working_dir, true);
+ if (!WorkingDir || WorkingDir.GetFileType() != FileSpec::eFileTypeDirectory)
+ {
+ error.SetErrorStringWithFormat("No such file or directory: %s", working_dir);
+ return error;
+ }
+ }
+
SetPrivateState(eStateLaunching);
const lldb_private::ProcessLaunchInfo::FileAction *file_action;
@@ -170,7 +181,7 @@ ProcessPOSIX::DoLaunch (Module *module,
const char *stdin_path = NULL;
const char *stdout_path = NULL;
const char *stderr_path = NULL;
-
+
file_action = launch_info.GetFileActionForFD (STDIN_FILENO);
stdin_path = GetFilePath(file_action, stdin_path);
@@ -187,6 +198,7 @@ ProcessPOSIX::DoLaunch (Module *module,
stdin_path,
stdout_path,
stderr_path,
+ working_dir,
error);
m_module = module;
@@ -194,6 +206,8 @@ ProcessPOSIX::DoLaunch (Module *module,
if (!error.Success())
return error;
+ SetSTDIOFileDescriptor(m_monitor->GetTerminalFD());
+
SetID(m_monitor->GetPID());
return error;
}
@@ -265,7 +279,6 @@ ProcessPOSIX::DoHalt(bool &caused_stop)
{
caused_stop = true;
}
-
return error;
}
@@ -349,13 +362,26 @@ ProcessPOSIX::SendMessage(const ProcessM
case ProcessMessage::eSignalMessage:
case ProcessMessage::eSignalDeliveredMessage:
- SetPrivateState(eStateStopped);
- break;
+ {
+ lldb::tid_t tid = message.GetTID();
+ lldb::tid_t pid = GetID();
+ if (tid == pid) {
+ SetPrivateState(eStateStopped);
+ break;
+ } else {
+ // FIXME: Ignore any signals generated by children.
+ return;
+ }
+ }
case ProcessMessage::eCrashMessage:
// FIXME: Update stop reason as per bugzilla 14598
SetPrivateState(eStateStopped);
break;
+
+ case ProcessMessage::eNewThreadMessage:
+ SetPrivateState(eStateStopped);
+ break;
}
m_message_queue.push(message);
@@ -364,7 +390,7 @@ ProcessPOSIX::SendMessage(const ProcessM
void
ProcessPOSIX::RefreshStateAfterStop()
{
- LogSP log (ProcessPOSIXLog::GetLogIfAllCategoriesSet (POSIX_LOG_PROCESS));
+ Log *log (ProcessPOSIXLog::GetLogIfAllCategoriesSet (POSIX_LOG_PROCESS));
if (log && log->GetMask().Test(POSIX_LOG_VERBOSE))
log->Printf ("ProcessPOSIX::%s()", __FUNCTION__);
@@ -383,6 +409,12 @@ ProcessPOSIX::RefreshStateAfterStop()
POSIXThread *thread = static_cast<POSIXThread*>(
GetThreadList().FindThreadByID(tid, false).get());
+ if (message.GetKind() == ProcessMessage::eNewThreadMessage) {
+ ThreadSP thread_sp;
+ thread_sp.reset(new POSIXThread(*this, message.GetChildTID()));
+ m_thread_list.AddThread(thread_sp);
+ }
+
assert(thread);
thread->Notify(message);
@@ -393,7 +425,10 @@ bool
ProcessPOSIX::IsAlive()
{
StateType state = GetPrivateState();
- return state != eStateDetached && state != eStateExited && state != eStateInvalid;
+ return state != eStateDetached
+ && state != eStateExited
+ && state != eStateInvalid
+ && state != eStateUnloaded;
}
size_t
@@ -452,6 +487,20 @@ ProcessPOSIX::DoDeallocateMemory(lldb::a
return error;
}
+addr_t
+ProcessPOSIX::ResolveIndirectFunction(const Address *address, Error &error)
+{
+ addr_t function_addr = LLDB_INVALID_ADDRESS;
+ if (address == NULL) {
+ error.SetErrorStringWithFormat("unable to determine direct function call for NULL address");
+ } else if (!InferiorCall(this, address, function_addr)) {
+ function_addr = LLDB_INVALID_ADDRESS;
+ error.SetErrorStringWithFormat("unable to determine direct function call for indirect function %s",
+ address->CalculateSymbolContextSymbol()->GetName().AsCString());
+ }
+ return function_addr;
+}
+
size_t
ProcessPOSIX::GetSoftwareBreakpointTrapOpcode(BreakpointSite* bp_site)
{
@@ -479,13 +528,13 @@ ProcessPOSIX::GetSoftwareBreakpointTrapO
}
Error
-ProcessPOSIX::EnableBreakpoint(BreakpointSite *bp_site)
+ProcessPOSIX::EnableBreakpointSite(BreakpointSite *bp_site)
{
return EnableSoftwareBreakpoint(bp_site);
}
Error
-ProcessPOSIX::DisableBreakpoint(BreakpointSite *bp_site)
+ProcessPOSIX::DisableBreakpointSite(BreakpointSite *bp_site)
{
return DisableSoftwareBreakpoint(bp_site);
}
@@ -500,7 +549,7 @@ ProcessPOSIX::UpdateThreadListIfNeeded()
bool
ProcessPOSIX::UpdateThreadList(ThreadList &old_thread_list, ThreadList &new_thread_list)
{
- LogSP log (ProcessPOSIXLog::GetLogIfAllCategoriesSet (POSIX_LOG_THREAD));
+ Log *log (ProcessPOSIXLog::GetLogIfAllCategoriesSet (POSIX_LOG_THREAD));
if (log && log->GetMask().Test(POSIX_LOG_VERBOSE))
log->Printf ("ProcessPOSIX::%s() (pid = %" PRIi64 ")", __FUNCTION__, GetID());
@@ -539,27 +588,6 @@ ProcessPOSIX::PutSTDIN(const char *buf,
return status;
}
-size_t
-ProcessPOSIX::GetSTDOUT(char *buf, size_t len, Error &error)
-{
- ssize_t bytes_read;
-
- // The terminal file descriptor is always in non-block mode.
- if ((bytes_read = read(m_monitor->GetTerminalFD(), buf, len)) < 0)
- {
- if (errno != EAGAIN)
- error.SetErrorToErrno();
- return 0;
- }
- return bytes_read;
-}
-
-size_t
-ProcessPOSIX::GetSTDERR(char *buf, size_t len, Error &error)
-{
- return GetSTDOUT(buf, len, error);
-}
-
UnixSignals &
ProcessPOSIX::GetUnixSignals()
{
Modified: lldb/branches/windows/source/Plugins/Process/POSIX/ProcessPOSIX.h
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/windows/source/Plugins/Process/POSIX/ProcessPOSIX.h?rev=179679&r1=179678&r2=179679&view=diff
==============================================================================
--- lldb/branches/windows/source/Plugins/Process/POSIX/ProcessPOSIX.h (original)
+++ lldb/branches/windows/source/Plugins/Process/POSIX/ProcessPOSIX.h Wed Apr 17 03:38:48 2013
@@ -96,14 +96,17 @@ public:
virtual lldb_private::Error
DoDeallocateMemory(lldb::addr_t ptr);
+ virtual lldb::addr_t
+ ResolveIndirectFunction(const lldb_private::Address *address, lldb_private::Error &error);
+
virtual size_t
GetSoftwareBreakpointTrapOpcode(lldb_private::BreakpointSite* bp_site);
virtual lldb_private::Error
- EnableBreakpoint(lldb_private::BreakpointSite *bp_site);
+ EnableBreakpointSite(lldb_private::BreakpointSite *bp_site);
virtual lldb_private::Error
- DisableBreakpoint(lldb_private::BreakpointSite *bp_site);
+ DisableBreakpointSite(lldb_private::BreakpointSite *bp_site);
virtual uint32_t
UpdateThreadListIfNeeded();
@@ -121,12 +124,6 @@ public:
virtual size_t
PutSTDIN(const char *buf, size_t len, lldb_private::Error &error);
- virtual size_t
- GetSTDOUT(char *buf, size_t len, lldb_private::Error &error);
-
- virtual size_t
- GetSTDERR(char *buf, size_t len, lldb_private::Error &error);
-
//--------------------------------------------------------------------------
// ProcessPOSIX internal API.
Modified: lldb/branches/windows/source/Plugins/Process/POSIX/ProcessPOSIXLog.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/windows/source/Plugins/Process/POSIX/ProcessPOSIXLog.cpp?rev=179679&r1=179678&r2=179679&view=diff
==============================================================================
--- lldb/branches/windows/source/Plugins/Process/POSIX/ProcessPOSIXLog.cpp (original)
+++ lldb/branches/windows/source/Plugins/Process/POSIX/ProcessPOSIXLog.cpp Wed Apr 17 03:38:48 2013
@@ -21,24 +21,28 @@ using namespace lldb_private;
// We want to avoid global constructors where code needs to be run so here we
// control access to our static g_log_sp by hiding it in a singleton function
-// that will construct the static g_lob_sp the first time this function is
+// that will construct the static g_log_sp the first time this function is
// called.
-static LogSP &
+static bool g_log_enabled = false;
+static Log * g_log = NULL;
+static Log *
GetLog ()
{
- static LogSP g_log_sp;
- return g_log_sp;
+ if (!g_log_enabled)
+ return NULL;
+ return g_log;
}
-LogSP
+
+Log *
ProcessPOSIXLog::GetLogIfAllCategoriesSet (uint32_t mask)
{
- LogSP log(GetLog ());
+ Log *log(GetLog ());
if (log && mask)
{
uint32_t log_mask = log->GetMask().Get();
if ((log_mask & mask) != mask)
- return LogSP();
+ return NULL;
}
return log;
}
@@ -46,7 +50,7 @@ ProcessPOSIXLog::GetLogIfAllCategoriesSe
void
ProcessPOSIXLog::DisableLog (const char **args, Stream *feedback_strm)
{
- LogSP log (GetLog ());
+ Log *log (GetLog ());
if (log)
{
uint32_t flag_bits = 0;
@@ -79,33 +83,33 @@ ProcessPOSIXLog::DisableLog (const char
}
}
+ log->GetMask().Reset (flag_bits);
if (flag_bits == 0)
- GetLog ().reset();
- else
- log->GetMask().Reset (flag_bits);
+ g_log_enabled = false;
}
return;
}
-LogSP
+Log *
ProcessPOSIXLog::EnableLog (StreamSP &log_stream_sp, uint32_t log_options, const char **args, Stream *feedback_strm)
{
// Try see if there already is a log - that way we can reuse its settings.
// We could reuse the log in toto, but we don't know that the stream is the same.
uint32_t flag_bits = 0;
- LogSP log(GetLog ());
- if (log)
- flag_bits = log->GetMask().Get();
+ if (g_log)
+ flag_bits = g_log->GetMask().Get();
// Now make a new log with this stream if one was provided
if (log_stream_sp)
{
- log = LogSP(new Log(log_stream_sp));
- GetLog () = log;
+ if (g_log)
+ g_log->SetStream(log_stream_sp);
+ else
+ g_log = new Log(log_stream_sp);
}
- if (log)
+ if (g_log)
{
bool got_unknown_category = false;
for (; args[0]; args++)
@@ -140,10 +144,11 @@ ProcessPOSIXLog::EnableLog (StreamSP &lo
}
if (flag_bits == 0)
flag_bits = POSIX_LOG_DEFAULT;
- log->GetMask().Reset(flag_bits);
- log->GetOptions().Reset(log_options);
+ g_log->GetMask().Reset(flag_bits);
+ g_log->GetOptions().Reset(log_options);
+ g_log_enabled = true;
}
- return log;
+ return g_log;
}
void
@@ -174,7 +179,7 @@ ProcessPOSIXLog::ListLogCategories (Stre
void
ProcessPOSIXLog::LogIf (uint32_t mask, const char *format, ...)
{
- LogSP log (ProcessPOSIXLog::GetLogIfAllCategoriesSet (mask));
+ Log *log (ProcessPOSIXLog::GetLogIfAllCategoriesSet (mask));
if (log)
{
va_list args;
Modified: lldb/branches/windows/source/Plugins/Process/POSIX/ProcessPOSIXLog.h
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/windows/source/Plugins/Process/POSIX/ProcessPOSIXLog.h?rev=179679&r1=179678&r2=179679&view=diff
==============================================================================
--- lldb/branches/windows/source/Plugins/Process/POSIX/ProcessPOSIXLog.h (original)
+++ lldb/branches/windows/source/Plugins/Process/POSIX/ProcessPOSIXLog.h Wed Apr 17 03:38:48 2013
@@ -50,13 +50,13 @@ public:
}
- static lldb::LogSP
+ static lldb_private::Log *
GetLogIfAllCategoriesSet(uint32_t mask = 0);
static void
DisableLog (const char **args, lldb_private::Stream *feedback_strm);
- static lldb::LogSP
+ static lldb_private::Log *
EnableLog (lldb::StreamSP &log_stream_sp, uint32_t log_options,
const char **args, lldb_private::Stream *feedback_strm);
Modified: lldb/branches/windows/source/Plugins/Process/POSIX/RegisterContext_i386.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/windows/source/Plugins/Process/POSIX/RegisterContext_i386.cpp?rev=179679&r1=179678&r2=179679&view=diff
==============================================================================
--- lldb/branches/windows/source/Plugins/Process/POSIX/RegisterContext_i386.cpp (original)
+++ lldb/branches/windows/source/Plugins/Process/POSIX/RegisterContext_i386.cpp Wed Apr 17 03:38:48 2013
@@ -15,6 +15,7 @@
#include "ProcessPOSIXLog.h"
#include "ProcessMonitor.h"
#include "RegisterContext_i386.h"
+#include "RegisterContext_x86.h"
using namespace lldb_private;
using namespace lldb;
@@ -82,103 +83,6 @@ enum
k_num_register_sets = 2
};
-enum
-{
- gcc_eax = 0,
- gcc_ecx,
- gcc_edx,
- gcc_ebx,
- gcc_ebp,
- gcc_esp,
- gcc_esi,
- gcc_edi,
- gcc_eip,
- gcc_eflags
-};
-
-enum
-{
- dwarf_eax = 0,
- dwarf_ecx,
- dwarf_edx,
- dwarf_ebx,
- dwarf_esp,
- dwarf_ebp,
- dwarf_esi,
- dwarf_edi,
- dwarf_eip,
- dwarf_eflags,
- dwarf_stmm0 = 11,
- dwarf_stmm1,
- dwarf_stmm2,
- dwarf_stmm3,
- dwarf_stmm4,
- dwarf_stmm5,
- dwarf_stmm6,
- dwarf_stmm7,
- dwarf_xmm0 = 21,
- dwarf_xmm1,
- dwarf_xmm2,
- dwarf_xmm3,
- dwarf_xmm4,
- dwarf_xmm5,
- dwarf_xmm6,
- dwarf_xmm7
-};
-
-enum
-{
- gdb_eax = 0,
- gdb_ecx = 1,
- gdb_edx = 2,
- gdb_ebx = 3,
- gdb_esp = 4,
- gdb_ebp = 5,
- gdb_esi = 6,
- gdb_edi = 7,
- gdb_eip = 8,
- gdb_eflags = 9,
- gdb_cs = 10,
- gdb_ss = 11,
- gdb_ds = 12,
- gdb_es = 13,
- gdb_fs = 14,
- gdb_gs = 15,
- gdb_stmm0 = 16,
- gdb_stmm1 = 17,
- gdb_stmm2 = 18,
- gdb_stmm3 = 19,
- gdb_stmm4 = 20,
- gdb_stmm5 = 21,
- gdb_stmm6 = 22,
- gdb_stmm7 = 23,
- gdb_fcw = 24,
- gdb_fsw = 25,
- gdb_ftw = 26,
- gdb_fpu_cs = 27,
- gdb_ip = 28,
- gdb_fpu_ds = 29,
- gdb_dp = 30,
- gdb_fop = 31,
- gdb_xmm0 = 32,
- gdb_xmm1 = 33,
- gdb_xmm2 = 34,
- gdb_xmm3 = 35,
- gdb_xmm4 = 36,
- gdb_xmm5 = 37,
- gdb_xmm6 = 38,
- gdb_xmm7 = 39,
- gdb_mxcsr = 40,
- gdb_mm0 = 41,
- gdb_mm1 = 42,
- gdb_mm2 = 43,
- gdb_mm3 = 44,
- gdb_mm4 = 45,
- gdb_mm5 = 46,
- gdb_mm6 = 47,
- gdb_mm7 = 48
-};
-
static const
uint32_t g_gpr_regnums[k_num_gpr_registers] =
{
@@ -387,7 +291,7 @@ RegisterContext_i386::GetRegisterCount()
}
const RegisterInfo *
-RegisterContext_i386::GetRegisterInfoAtIndex(uint32_t reg)
+RegisterContext_i386::GetRegisterInfoAtIndex(size_t reg)
{
assert(k_num_register_infos == k_num_registers);
if (reg < k_num_registers)
@@ -403,7 +307,7 @@ RegisterContext_i386::GetRegisterSetCoun
}
const RegisterSet *
-RegisterContext_i386::GetRegisterSet(uint32_t set)
+RegisterContext_i386::GetRegisterSet(size_t set)
{
if (set < k_num_register_sets)
return &g_reg_sets[set];
@@ -612,7 +516,7 @@ RegisterContext_i386::HardwareSingleStep
void
RegisterContext_i386::LogGPR(const char *title)
{
- LogSP log (ProcessPOSIXLog::GetLogIfAllCategoriesSet (POSIX_LOG_REGISTERS));
+ Log *log (ProcessPOSIXLog::GetLogIfAllCategoriesSet (POSIX_LOG_REGISTERS));
if (log)
{
if (title)
@@ -631,7 +535,7 @@ RegisterContext_i386::ReadGPR()
bool result;
ProcessMonitor &monitor = GetMonitor();
- result = monitor.ReadGPR(m_thread.GetID(), &user.regs);
+ result = monitor.ReadGPR(m_thread.GetID(), &user.regs, sizeof(user.regs));
LogGPR("RegisterContext_i386::ReadGPR()");
return result;
}
@@ -640,5 +544,5 @@ bool
RegisterContext_i386::ReadFPR()
{
ProcessMonitor &monitor = GetMonitor();
- return monitor.ReadFPR(m_thread.GetID(), &user.i387);
+ return monitor.ReadFPR(m_thread.GetID(), &user.i387, sizeof(user.i387));
}
Modified: lldb/branches/windows/source/Plugins/Process/POSIX/RegisterContext_i386.h
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/windows/source/Plugins/Process/POSIX/RegisterContext_i386.h?rev=179679&r1=179678&r2=179679&view=diff
==============================================================================
--- lldb/branches/windows/source/Plugins/Process/POSIX/RegisterContext_i386.h (original)
+++ lldb/branches/windows/source/Plugins/Process/POSIX/RegisterContext_i386.h Wed Apr 17 03:38:48 2013
@@ -35,13 +35,13 @@ public:
GetRegisterCount();
const lldb_private::RegisterInfo *
- GetRegisterInfoAtIndex(uint32_t reg);
+ GetRegisterInfoAtIndex(size_t reg);
size_t
GetRegisterSetCount();
const lldb_private::RegisterSet *
- GetRegisterSet(uint32_t set);
+ GetRegisterSet(size_t set);
static unsigned
GetRegisterIndexFromOffset(unsigned offset);
Modified: lldb/branches/windows/source/Plugins/Process/POSIX/RegisterContext_x86_64.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/windows/source/Plugins/Process/POSIX/RegisterContext_x86_64.cpp?rev=179679&r1=179678&r2=179679&view=diff
==============================================================================
--- lldb/branches/windows/source/Plugins/Process/POSIX/RegisterContext_x86_64.cpp (original)
+++ lldb/branches/windows/source/Plugins/Process/POSIX/RegisterContext_x86_64.cpp Wed Apr 17 03:38:48 2013
@@ -15,11 +15,14 @@
#include "lldb/Core/DataExtractor.h"
#include "lldb/Core/RegisterValue.h"
#include "lldb/Core/Scalar.h"
+#include "lldb/Target/Target.h"
#include "lldb/Target/Thread.h"
#include "lldb/Host/Endian.h"
#include "ProcessPOSIX.h"
#include "ProcessMonitor.h"
+#include "RegisterContext_i386.h"
+#include "RegisterContext_x86.h"
#include "RegisterContext_x86_64.h"
using namespace lldb_private;
@@ -53,7 +56,17 @@ enum
gpr_ss,
gpr_ds,
gpr_es,
- k_last_gpr = gpr_es,
+ gpr_eax,
+ gpr_ebx,
+ gpr_ecx,
+ gpr_edx,
+ gpr_edi,
+ gpr_esi,
+ gpr_ebp,
+ gpr_esp,
+ gpr_eip,
+ gpr_eflags,
+ k_last_gpr = gpr_eflags,
k_first_fpr,
fpu_fcw = k_first_fpr,
@@ -92,19 +105,34 @@ enum
fpu_xmm15,
k_last_fpr = fpu_xmm15,
- k_num_registers,
+ k_num_registers, // TODO: Add support for AVX registers
+
+ k_first_avx,
+ fpu_ymm0 = k_first_avx,
+ fpu_ymm1,
+ fpu_ymm2,
+ fpu_ymm3,
+ fpu_ymm4,
+ fpu_ymm5,
+ fpu_ymm6,
+ fpu_ymm7,
+ fpu_ymm8,
+ fpu_ymm9,
+ fpu_ymm10,
+ fpu_ymm11,
+ fpu_ymm12,
+ fpu_ymm13,
+ fpu_ymm14,
+ fpu_ymm15,
+ k_last_avx = fpu_ymm15,
+
k_num_gpr_registers = k_last_gpr - k_first_gpr + 1,
- k_num_fpu_registers = k_last_fpr - k_first_fpr + 1
+ k_num_fpu_registers = k_last_fpr - k_first_fpr + 1,
+ k_num_avx_registers = k_last_avx - k_first_avx + 1
};
-// Number of register sets provided by this context.
enum
{
- k_num_register_sets = 2
-};
-
-enum gcc_dwarf_regnums
-{
gcc_dwarf_gpr_rax = 0,
gcc_dwarf_gpr_rdx,
gcc_dwarf_gpr_rcx,
@@ -148,7 +176,7 @@ enum gcc_dwarf_regnums
gcc_dwarf_fpu_stmm7
};
-enum gdb_regnums
+enum
{
gdb_gpr_rax = 0,
gdb_gpr_rbx = 1,
@@ -185,9 +213,9 @@ enum gdb_regnums
gdb_fpu_fcw = 32,
gdb_fpu_fsw = 33,
gdb_fpu_ftw = 34,
- gdb_fpu_cs = 35,
+ gdb_fpu_cs_64 = 35,
gdb_fpu_ip = 36,
- gdb_fpu_ds = 37,
+ gdb_fpu_ds_64 = 37,
gdb_fpu_dp = 38,
gdb_fpu_fop = 39,
gdb_fpu_xmm0 = 40,
@@ -235,7 +263,17 @@ uint32_t g_gpr_regnums[k_num_gpr_registe
gpr_gs,
gpr_ss,
gpr_ds,
- gpr_es
+ gpr_es,
+ gpr_eax,
+ gpr_ebx,
+ gpr_ecx,
+ gpr_edx,
+ gpr_edi,
+ gpr_esi,
+ gpr_ebp,
+ gpr_esp,
+ gpr_eip,
+ gpr_eflags
};
static const uint32_t
@@ -277,11 +315,40 @@ g_fpu_regnums[k_num_fpu_registers] =
fpu_xmm15
};
+static const uint32_t
+g_avx_regnums[k_num_avx_registers] =
+{
+ fpu_ymm0,
+ fpu_ymm1,
+ fpu_ymm2,
+ fpu_ymm3,
+ fpu_ymm4,
+ fpu_ymm5,
+ fpu_ymm6,
+ fpu_ymm7,
+ fpu_ymm8,
+ fpu_ymm9,
+ fpu_ymm10,
+ fpu_ymm11,
+ fpu_ymm12,
+ fpu_ymm13,
+ fpu_ymm14,
+ fpu_ymm15
+};
+
+// Number of register sets provided by this context.
+enum
+{
+ k_num_extended_register_sets = 1,
+ k_num_register_sets = 3
+};
+
static const RegisterSet
g_reg_sets[k_num_register_sets] =
{
- { "General Purpose Registers", "gpr", k_num_gpr_registers, g_gpr_regnums },
- { "Floating Point Registers", "fpu", k_num_fpu_registers, g_fpu_regnums }
+ { "General Purpose Registers", "gpr", k_num_gpr_registers, g_gpr_regnums },
+ { "Floating Point Registers", "fpu", k_num_fpu_registers, g_fpu_regnums },
+ { "Advanced Vector Extensions", "avx", k_num_avx_registers, g_avx_regnums }
};
// Computes the offset of the given GPR in the user data area.
@@ -297,6 +364,9 @@ g_reg_sets[k_num_register_sets] =
// Number of bytes needed to represent a GPR.
#define GPR_SIZE(reg) sizeof(((GPR*)NULL)->reg)
+// Number of bytes needed to represent a i386 GPR
+#define GPR_i386_SIZE(reg) sizeof(((RegisterContext_i386::GPR*)NULL)->reg)
+
// Number of bytes needed to represent a FPR.
#define FPR_SIZE(reg) sizeof(((RegisterContext_x86_64::FPU*)NULL)->reg)
@@ -310,6 +380,10 @@ g_reg_sets[k_num_register_sets] =
{ #reg, alt, GPR_SIZE(reg), GPR_OFFSET(reg), eEncodingUint, \
eFormatHex, { kind1, kind2, kind3, kind4, gpr_##reg }, NULL, NULL }
+#define DEFINE_GPR_i386(reg_i386, reg_x86_64, alt, kind1, kind2, kind3, kind4) \
+ { #reg_i386, alt, GPR_i386_SIZE(reg_i386), GPR_OFFSET(reg_x86_64), eEncodingUint, \
+ eFormatHex, { kind1, kind2, kind3, kind4, gpr_##reg_i386 }, NULL, NULL }
+
#define DEFINE_FPR(reg, kind1, kind2, kind3, kind4) \
{ #reg, NULL, FPR_SIZE(reg), FPR_OFFSET(reg), eEncodingUint, \
eFormatHex, { kind1, kind2, kind3, kind4, fpu_##reg }, NULL, NULL }
@@ -356,7 +430,17 @@ g_register_infos[k_num_registers] =
DEFINE_GPR(ss, NULL, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gdb_gpr_ss),
DEFINE_GPR(ds, NULL, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gdb_gpr_ds),
DEFINE_GPR(es, NULL, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gdb_gpr_es),
-
+ // i386 registers
+ DEFINE_GPR_i386(eax, rax, NULL, gcc_eax, dwarf_eax, LLDB_INVALID_REGNUM, gdb_eax),
+ DEFINE_GPR_i386(ebx, rbx, NULL, gcc_ebx, dwarf_ebx, LLDB_INVALID_REGNUM, gdb_ebx),
+ DEFINE_GPR_i386(ecx, rcx, NULL, gcc_ecx, dwarf_ecx, LLDB_INVALID_REGNUM, gdb_ecx),
+ DEFINE_GPR_i386(edx, rdx, NULL, gcc_edx, dwarf_edx, LLDB_INVALID_REGNUM, gdb_edx),
+ DEFINE_GPR_i386(edi, rdi, NULL, gcc_edi, dwarf_edi, LLDB_INVALID_REGNUM, gdb_edi),
+ DEFINE_GPR_i386(esi, rsi, NULL, gcc_esi, dwarf_esi, LLDB_INVALID_REGNUM, gdb_esi),
+ DEFINE_GPR_i386(ebp, rbp, "fp", gcc_ebp, dwarf_ebp, LLDB_REGNUM_GENERIC_FP, gdb_ebp),
+ DEFINE_GPR_i386(esp, rsp, "sp", gcc_esp, dwarf_esp, LLDB_REGNUM_GENERIC_SP, gdb_esp),
+ DEFINE_GPR_i386(eip, rip, "pc", gcc_eip, dwarf_eip, LLDB_REGNUM_GENERIC_PC, gdb_eip),
+ DEFINE_GPR_i386(eflags, rflags, "flags", gcc_eflags, dwarf_eflags, LLDB_REGNUM_GENERIC_FLAGS, gdb_eflags),
// i387 Floating point registers.
DEFINE_FPR(fcw, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gdb_fpu_fcw),
DEFINE_FPR(fsw, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gdb_fpu_fsw),
@@ -364,10 +448,10 @@ g_register_infos[k_num_registers] =
DEFINE_FPR(fop, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gdb_fpu_fop),
DEFINE_FPR(ip, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gdb_fpu_ip),
// FIXME: Extract segment from ip.
- DEFINE_FPR(ip, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gdb_fpu_cs),
+ DEFINE_FPR(ip, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gdb_fpu_cs_64),
DEFINE_FPR(dp, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gdb_fpu_dp),
// FIXME: Extract segment from dp.
- DEFINE_FPR(dp, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gdb_fpu_ds),
+ DEFINE_FPR(dp, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gdb_fpu_ds_64),
DEFINE_FPR(mxcsr, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, gdb_fpu_mxcsr),
DEFINE_FPR(mxcsrmask, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM),
@@ -422,8 +506,13 @@ static bool IsFPR(unsigned reg)
return (k_first_fpr <= reg && reg <= k_last_fpr);
}
+static bool IsAVX(unsigned reg)
+{
+ return (k_first_avx <= reg && reg <= k_last_avx);
+}
+
RegisterContext_x86_64::RegisterContext_x86_64(Thread &thread,
- uint32_t concrete_frame_idx)
+ uint32_t concrete_frame_idx)
: RegisterContextPOSIX(thread, concrete_frame_idx)
{
}
@@ -457,7 +546,7 @@ RegisterContext_x86_64::GetRegisterCount
}
const RegisterInfo *
-RegisterContext_x86_64::GetRegisterInfoAtIndex(uint32_t reg)
+RegisterContext_x86_64::GetRegisterInfoAtIndex(size_t reg)
{
if (reg < k_num_registers)
return &g_register_infos[reg];
@@ -468,13 +557,18 @@ RegisterContext_x86_64::GetRegisterInfoA
size_t
RegisterContext_x86_64::GetRegisterSetCount()
{
- return k_num_register_sets;
+ size_t sets = 0;
+ for (size_t set = 0; set < k_num_register_sets; ++set)
+ if (IsRegisterSetAvailable(set))
+ ++sets;
+
+ return sets;
}
const RegisterSet *
-RegisterContext_x86_64::GetRegisterSet(uint32_t set)
+RegisterContext_x86_64::GetRegisterSet(size_t set)
{
- if (set < k_num_register_sets)
+ if (IsRegisterSetAvailable(set))
return &g_reg_sets[set];
else
return NULL;
@@ -501,17 +595,27 @@ RegisterContext_x86_64::GetRegisterName(
}
bool
+RegisterContext_x86_64::IsRegisterSetAvailable(size_t set_index)
+{
+ // Note: Extended register sets are assumed to be at the end of g_reg_sets.
+ return (set_index < k_num_register_sets - k_num_extended_register_sets);
+}
+
+bool
RegisterContext_x86_64::ReadRegister(const RegisterInfo *reg_info, RegisterValue &value)
{
const uint32_t reg = reg_info->kinds[eRegisterKindLLDB];
- if (reg >= k_first_fpr && reg <= k_last_fpr) {
+ if (IsAVX(reg))
+ return false;
+
+ if (IsFPR(reg)) {
if (!ReadFPR())
return false;
}
else {
ProcessMonitor &monitor = GetMonitor();
- return monitor.ReadRegisterValue(m_thread.GetID(), GetRegOffset(reg),GetRegSize(reg), value);
+ return monitor.ReadRegisterValue(m_thread.GetID(), GetRegOffset(reg), GetRegSize(reg), value);
}
if (reg_info->encoding == eEncodingVector) {
@@ -584,6 +688,9 @@ RegisterContext_x86_64::WriteRegister(co
const lldb_private::RegisterValue &value)
{
const uint32_t reg = reg_info->kinds[eRegisterKindLLDB];
+ if (IsAVX(reg))
+ return false;
+
ProcessMonitor &monitor = GetMonitor();
return monitor.WriteRegisterValue(m_thread.GetID(), GetRegOffset(reg), value);
}
@@ -620,138 +727,262 @@ uint32_t
RegisterContext_x86_64::ConvertRegisterKindToRegisterNumber(uint32_t kind,
uint32_t num)
{
- if (kind == eRegisterKindGeneric)
+ const Process *process = CalculateProcess().get();
+ if (process)
{
- switch (num)
+ const ArchSpec arch = process->GetTarget().GetArchitecture();;
+ switch (arch.GetCore())
{
- case LLDB_REGNUM_GENERIC_PC: return gpr_rip;
- case LLDB_REGNUM_GENERIC_SP: return gpr_rsp;
- case LLDB_REGNUM_GENERIC_FP: return gpr_rbp;
- case LLDB_REGNUM_GENERIC_FLAGS: return gpr_rflags;
- case LLDB_REGNUM_GENERIC_RA:
default:
- return LLDB_INVALID_REGNUM;
- }
- }
+ assert(false && "CPU type not supported!");
+ break;
- if (kind == eRegisterKindGCC || kind == eRegisterKindDWARF)
- {
- switch (num)
+ case ArchSpec::eCore_x86_32_i386:
+ case ArchSpec::eCore_x86_32_i486:
+ case ArchSpec::eCore_x86_32_i486sx:
{
- case gcc_dwarf_gpr_rax: return gpr_rax;
- case gcc_dwarf_gpr_rdx: return gpr_rdx;
- case gcc_dwarf_gpr_rcx: return gpr_rcx;
- case gcc_dwarf_gpr_rbx: return gpr_rbx;
- case gcc_dwarf_gpr_rsi: return gpr_rsi;
- case gcc_dwarf_gpr_rdi: return gpr_rdi;
- case gcc_dwarf_gpr_rbp: return gpr_rbp;
- case gcc_dwarf_gpr_rsp: return gpr_rsp;
- case gcc_dwarf_gpr_r8: return gpr_r8;
- case gcc_dwarf_gpr_r9: return gpr_r9;
- case gcc_dwarf_gpr_r10: return gpr_r10;
- case gcc_dwarf_gpr_r11: return gpr_r11;
- case gcc_dwarf_gpr_r12: return gpr_r12;
- case gcc_dwarf_gpr_r13: return gpr_r13;
- case gcc_dwarf_gpr_r14: return gpr_r14;
- case gcc_dwarf_gpr_r15: return gpr_r15;
- case gcc_dwarf_gpr_rip: return gpr_rip;
- case gcc_dwarf_fpu_xmm0: return fpu_xmm0;
- case gcc_dwarf_fpu_xmm1: return fpu_xmm1;
- case gcc_dwarf_fpu_xmm2: return fpu_xmm2;
- case gcc_dwarf_fpu_xmm3: return fpu_xmm3;
- case gcc_dwarf_fpu_xmm4: return fpu_xmm4;
- case gcc_dwarf_fpu_xmm5: return fpu_xmm5;
- case gcc_dwarf_fpu_xmm6: return fpu_xmm6;
- case gcc_dwarf_fpu_xmm7: return fpu_xmm7;
- case gcc_dwarf_fpu_xmm8: return fpu_xmm8;
- case gcc_dwarf_fpu_xmm9: return fpu_xmm9;
- case gcc_dwarf_fpu_xmm10: return fpu_xmm10;
- case gcc_dwarf_fpu_xmm11: return fpu_xmm11;
- case gcc_dwarf_fpu_xmm12: return fpu_xmm12;
- case gcc_dwarf_fpu_xmm13: return fpu_xmm13;
- case gcc_dwarf_fpu_xmm14: return fpu_xmm14;
- case gcc_dwarf_fpu_xmm15: return fpu_xmm15;
- case gcc_dwarf_fpu_stmm0: return fpu_stmm0;
- case gcc_dwarf_fpu_stmm1: return fpu_stmm1;
- case gcc_dwarf_fpu_stmm2: return fpu_stmm2;
- case gcc_dwarf_fpu_stmm3: return fpu_stmm3;
- case gcc_dwarf_fpu_stmm4: return fpu_stmm4;
- case gcc_dwarf_fpu_stmm5: return fpu_stmm5;
- case gcc_dwarf_fpu_stmm6: return fpu_stmm6;
- case gcc_dwarf_fpu_stmm7: return fpu_stmm7;
- default:
- return LLDB_INVALID_REGNUM;
+ if (kind == eRegisterKindGeneric)
+ {
+ switch (num)
+ {
+ case LLDB_REGNUM_GENERIC_PC: return gpr_eip;
+ case LLDB_REGNUM_GENERIC_SP: return gpr_esp;
+ case LLDB_REGNUM_GENERIC_FP: return gpr_ebp;
+ case LLDB_REGNUM_GENERIC_FLAGS: return gpr_eflags;
+ case LLDB_REGNUM_GENERIC_RA:
+ default:
+ return LLDB_INVALID_REGNUM;
+ }
+ }
+
+ if (kind == eRegisterKindGCC || kind == eRegisterKindDWARF)
+ {
+ switch (num)
+ {
+ case dwarf_eax: return gpr_eax;
+ case dwarf_edx: return gpr_edx;
+ case dwarf_ecx: return gpr_ecx;
+ case dwarf_ebx: return gpr_ebx;
+ case dwarf_esi: return gpr_esi;
+ case dwarf_edi: return gpr_edi;
+ case dwarf_ebp: return gpr_ebp;
+ case dwarf_esp: return gpr_esp;
+ case dwarf_eip: return gpr_eip;
+ case dwarf_xmm0: return fpu_xmm0;
+ case dwarf_xmm1: return fpu_xmm1;
+ case dwarf_xmm2: return fpu_xmm2;
+ case dwarf_xmm3: return fpu_xmm3;
+ case dwarf_xmm4: return fpu_xmm4;
+ case dwarf_xmm5: return fpu_xmm5;
+ case dwarf_xmm6: return fpu_xmm6;
+ case dwarf_xmm7: return fpu_xmm7;
+ case dwarf_stmm0: return fpu_stmm0;
+ case dwarf_stmm1: return fpu_stmm1;
+ case dwarf_stmm2: return fpu_stmm2;
+ case dwarf_stmm3: return fpu_stmm3;
+ case dwarf_stmm4: return fpu_stmm4;
+ case dwarf_stmm5: return fpu_stmm5;
+ case dwarf_stmm6: return fpu_stmm6;
+ case dwarf_stmm7: return fpu_stmm7;
+ default:
+ return LLDB_INVALID_REGNUM;
+ }
+ }
+
+ if (kind == eRegisterKindGDB)
+ {
+ switch (num)
+ {
+ case gdb_eax : return gpr_eax;
+ case gdb_ebx : return gpr_ebx;
+ case gdb_ecx : return gpr_ecx;
+ case gdb_edx : return gpr_edx;
+ case gdb_esi : return gpr_esi;
+ case gdb_edi : return gpr_edi;
+ case gdb_ebp : return gpr_ebp;
+ case gdb_esp : return gpr_esp;
+ case gdb_eip : return gpr_eip;
+ case gdb_eflags : return gpr_eflags;
+ case gdb_cs : return gpr_cs;
+ case gdb_ss : return gpr_ss;
+ case gdb_ds : return gpr_ds;
+ case gdb_es : return gpr_es;
+ case gdb_fs : return gpr_fs;
+ case gdb_gs : return gpr_gs;
+ case gdb_stmm0 : return fpu_stmm0;
+ case gdb_stmm1 : return fpu_stmm1;
+ case gdb_stmm2 : return fpu_stmm2;
+ case gdb_stmm3 : return fpu_stmm3;
+ case gdb_stmm4 : return fpu_stmm4;
+ case gdb_stmm5 : return fpu_stmm5;
+ case gdb_stmm6 : return fpu_stmm6;
+ case gdb_stmm7 : return fpu_stmm7;
+ case gdb_fcw : return fpu_fcw;
+ case gdb_fsw : return fpu_fsw;
+ case gdb_ftw : return fpu_ftw;
+ case gdb_fpu_cs : return fpu_cs;
+ case gdb_ip : return fpu_ip;
+ case gdb_fpu_ds : return fpu_ds; //fpu_fos
+ case gdb_dp : return fpu_dp; //fpu_foo
+ case gdb_fop : return fpu_fop;
+ case gdb_xmm0 : return fpu_xmm0;
+ case gdb_xmm1 : return fpu_xmm1;
+ case gdb_xmm2 : return fpu_xmm2;
+ case gdb_xmm3 : return fpu_xmm3;
+ case gdb_xmm4 : return fpu_xmm4;
+ case gdb_xmm5 : return fpu_xmm5;
+ case gdb_xmm6 : return fpu_xmm6;
+ case gdb_xmm7 : return fpu_xmm7;
+ case gdb_mxcsr : return fpu_mxcsr;
+ default:
+ return LLDB_INVALID_REGNUM;
+ }
+ }
+ else if (kind == eRegisterKindLLDB)
+ {
+ return num;
+ }
+
+ break;
}
- }
- if (kind == eRegisterKindGDB)
- {
- switch (num)
+ case ArchSpec::eCore_x86_64_x86_64:
{
- case gdb_gpr_rax : return gpr_rax;
- case gdb_gpr_rbx : return gpr_rbx;
- case gdb_gpr_rcx : return gpr_rcx;
- case gdb_gpr_rdx : return gpr_rdx;
- case gdb_gpr_rsi : return gpr_rsi;
- case gdb_gpr_rdi : return gpr_rdi;
- case gdb_gpr_rbp : return gpr_rbp;
- case gdb_gpr_rsp : return gpr_rsp;
- case gdb_gpr_r8 : return gpr_r8;
- case gdb_gpr_r9 : return gpr_r9;
- case gdb_gpr_r10 : return gpr_r10;
- case gdb_gpr_r11 : return gpr_r11;
- case gdb_gpr_r12 : return gpr_r12;
- case gdb_gpr_r13 : return gpr_r13;
- case gdb_gpr_r14 : return gpr_r14;
- case gdb_gpr_r15 : return gpr_r15;
- case gdb_gpr_rip : return gpr_rip;
- case gdb_gpr_rflags : return gpr_rflags;
- case gdb_gpr_cs : return gpr_cs;
- case gdb_gpr_ss : return gpr_ss;
- case gdb_gpr_ds : return gpr_ds;
- case gdb_gpr_es : return gpr_es;
- case gdb_gpr_fs : return gpr_fs;
- case gdb_gpr_gs : return gpr_gs;
- case gdb_fpu_stmm0 : return fpu_stmm0;
- case gdb_fpu_stmm1 : return fpu_stmm1;
- case gdb_fpu_stmm2 : return fpu_stmm2;
- case gdb_fpu_stmm3 : return fpu_stmm3;
- case gdb_fpu_stmm4 : return fpu_stmm4;
- case gdb_fpu_stmm5 : return fpu_stmm5;
- case gdb_fpu_stmm6 : return fpu_stmm6;
- case gdb_fpu_stmm7 : return fpu_stmm7;
- case gdb_fpu_fcw : return fpu_fcw;
- case gdb_fpu_fsw : return fpu_fsw;
- case gdb_fpu_ftw : return fpu_ftw;
- case gdb_fpu_cs : return fpu_cs;
- case gdb_fpu_ip : return fpu_ip;
- case gdb_fpu_ds : return fpu_ds;
- case gdb_fpu_dp : return fpu_dp;
- case gdb_fpu_fop : return fpu_fop;
- case gdb_fpu_xmm0 : return fpu_xmm0;
- case gdb_fpu_xmm1 : return fpu_xmm1;
- case gdb_fpu_xmm2 : return fpu_xmm2;
- case gdb_fpu_xmm3 : return fpu_xmm3;
- case gdb_fpu_xmm4 : return fpu_xmm4;
- case gdb_fpu_xmm5 : return fpu_xmm5;
- case gdb_fpu_xmm6 : return fpu_xmm6;
- case gdb_fpu_xmm7 : return fpu_xmm7;
- case gdb_fpu_xmm8 : return fpu_xmm8;
- case gdb_fpu_xmm9 : return fpu_xmm9;
- case gdb_fpu_xmm10 : return fpu_xmm10;
- case gdb_fpu_xmm11 : return fpu_xmm11;
- case gdb_fpu_xmm12 : return fpu_xmm12;
- case gdb_fpu_xmm13 : return fpu_xmm13;
- case gdb_fpu_xmm14 : return fpu_xmm14;
- case gdb_fpu_xmm15 : return fpu_xmm15;
- case gdb_fpu_mxcsr : return fpu_mxcsr;
- default:
- return LLDB_INVALID_REGNUM;
+ if (kind == eRegisterKindGeneric)
+ {
+ switch (num)
+ {
+ case LLDB_REGNUM_GENERIC_PC: return gpr_rip;
+ case LLDB_REGNUM_GENERIC_SP: return gpr_rsp;
+ case LLDB_REGNUM_GENERIC_FP: return gpr_rbp;
+ case LLDB_REGNUM_GENERIC_FLAGS: return gpr_rflags;
+ case LLDB_REGNUM_GENERIC_RA:
+ default:
+ return LLDB_INVALID_REGNUM;
+ }
+ }
+
+ if (kind == eRegisterKindGCC || kind == eRegisterKindDWARF)
+ {
+ switch (num)
+ {
+ case gcc_dwarf_gpr_rax: return gpr_rax;
+ case gcc_dwarf_gpr_rdx: return gpr_rdx;
+ case gcc_dwarf_gpr_rcx: return gpr_rcx;
+ case gcc_dwarf_gpr_rbx: return gpr_rbx;
+ case gcc_dwarf_gpr_rsi: return gpr_rsi;
+ case gcc_dwarf_gpr_rdi: return gpr_rdi;
+ case gcc_dwarf_gpr_rbp: return gpr_rbp;
+ case gcc_dwarf_gpr_rsp: return gpr_rsp;
+ case gcc_dwarf_gpr_r8: return gpr_r8;
+ case gcc_dwarf_gpr_r9: return gpr_r9;
+ case gcc_dwarf_gpr_r10: return gpr_r10;
+ case gcc_dwarf_gpr_r11: return gpr_r11;
+ case gcc_dwarf_gpr_r12: return gpr_r12;
+ case gcc_dwarf_gpr_r13: return gpr_r13;
+ case gcc_dwarf_gpr_r14: return gpr_r14;
+ case gcc_dwarf_gpr_r15: return gpr_r15;
+ case gcc_dwarf_gpr_rip: return gpr_rip;
+ case gcc_dwarf_fpu_xmm0: return fpu_xmm0;
+ case gcc_dwarf_fpu_xmm1: return fpu_xmm1;
+ case gcc_dwarf_fpu_xmm2: return fpu_xmm2;
+ case gcc_dwarf_fpu_xmm3: return fpu_xmm3;
+ case gcc_dwarf_fpu_xmm4: return fpu_xmm4;
+ case gcc_dwarf_fpu_xmm5: return fpu_xmm5;
+ case gcc_dwarf_fpu_xmm6: return fpu_xmm6;
+ case gcc_dwarf_fpu_xmm7: return fpu_xmm7;
+ case gcc_dwarf_fpu_xmm8: return fpu_xmm8;
+ case gcc_dwarf_fpu_xmm9: return fpu_xmm9;
+ case gcc_dwarf_fpu_xmm10: return fpu_xmm10;
+ case gcc_dwarf_fpu_xmm11: return fpu_xmm11;
+ case gcc_dwarf_fpu_xmm12: return fpu_xmm12;
+ case gcc_dwarf_fpu_xmm13: return fpu_xmm13;
+ case gcc_dwarf_fpu_xmm14: return fpu_xmm14;
+ case gcc_dwarf_fpu_xmm15: return fpu_xmm15;
+ case gcc_dwarf_fpu_stmm0: return fpu_stmm0;
+ case gcc_dwarf_fpu_stmm1: return fpu_stmm1;
+ case gcc_dwarf_fpu_stmm2: return fpu_stmm2;
+ case gcc_dwarf_fpu_stmm3: return fpu_stmm3;
+ case gcc_dwarf_fpu_stmm4: return fpu_stmm4;
+ case gcc_dwarf_fpu_stmm5: return fpu_stmm5;
+ case gcc_dwarf_fpu_stmm6: return fpu_stmm6;
+ case gcc_dwarf_fpu_stmm7: return fpu_stmm7;
+ default:
+ return LLDB_INVALID_REGNUM;
+ }
+ }
+
+ if (kind == eRegisterKindGDB)
+ {
+ switch (num)
+ {
+ case gdb_gpr_rax : return gpr_rax;
+ case gdb_gpr_rbx : return gpr_rbx;
+ case gdb_gpr_rcx : return gpr_rcx;
+ case gdb_gpr_rdx : return gpr_rdx;
+ case gdb_gpr_rsi : return gpr_rsi;
+ case gdb_gpr_rdi : return gpr_rdi;
+ case gdb_gpr_rbp : return gpr_rbp;
+ case gdb_gpr_rsp : return gpr_rsp;
+ case gdb_gpr_r8 : return gpr_r8;
+ case gdb_gpr_r9 : return gpr_r9;
+ case gdb_gpr_r10 : return gpr_r10;
+ case gdb_gpr_r11 : return gpr_r11;
+ case gdb_gpr_r12 : return gpr_r12;
+ case gdb_gpr_r13 : return gpr_r13;
+ case gdb_gpr_r14 : return gpr_r14;
+ case gdb_gpr_r15 : return gpr_r15;
+ case gdb_gpr_rip : return gpr_rip;
+ case gdb_gpr_rflags : return gpr_rflags;
+ case gdb_gpr_cs : return gpr_cs;
+ case gdb_gpr_ss : return gpr_ss;
+ case gdb_gpr_ds : return gpr_ds;
+ case gdb_gpr_es : return gpr_es;
+ case gdb_gpr_fs : return gpr_fs;
+ case gdb_gpr_gs : return gpr_gs;
+ case gdb_fpu_stmm0 : return fpu_stmm0;
+ case gdb_fpu_stmm1 : return fpu_stmm1;
+ case gdb_fpu_stmm2 : return fpu_stmm2;
+ case gdb_fpu_stmm3 : return fpu_stmm3;
+ case gdb_fpu_stmm4 : return fpu_stmm4;
+ case gdb_fpu_stmm5 : return fpu_stmm5;
+ case gdb_fpu_stmm6 : return fpu_stmm6;
+ case gdb_fpu_stmm7 : return fpu_stmm7;
+ case gdb_fpu_fcw : return fpu_fcw;
+ case gdb_fpu_fsw : return fpu_fsw;
+ case gdb_fpu_ftw : return fpu_ftw;
+ case gdb_fpu_cs_64 : return fpu_cs;
+ case gdb_fpu_ip : return fpu_ip;
+ case gdb_fpu_ds_64 : return fpu_ds;
+ case gdb_fpu_dp : return fpu_dp;
+ case gdb_fpu_fop : return fpu_fop;
+ case gdb_fpu_xmm0 : return fpu_xmm0;
+ case gdb_fpu_xmm1 : return fpu_xmm1;
+ case gdb_fpu_xmm2 : return fpu_xmm2;
+ case gdb_fpu_xmm3 : return fpu_xmm3;
+ case gdb_fpu_xmm4 : return fpu_xmm4;
+ case gdb_fpu_xmm5 : return fpu_xmm5;
+ case gdb_fpu_xmm6 : return fpu_xmm6;
+ case gdb_fpu_xmm7 : return fpu_xmm7;
+ case gdb_fpu_xmm8 : return fpu_xmm8;
+ case gdb_fpu_xmm9 : return fpu_xmm9;
+ case gdb_fpu_xmm10 : return fpu_xmm10;
+ case gdb_fpu_xmm11 : return fpu_xmm11;
+ case gdb_fpu_xmm12 : return fpu_xmm12;
+ case gdb_fpu_xmm13 : return fpu_xmm13;
+ case gdb_fpu_xmm14 : return fpu_xmm14;
+ case gdb_fpu_xmm15 : return fpu_xmm15;
+ case gdb_fpu_mxcsr : return fpu_mxcsr;
+ default:
+ return LLDB_INVALID_REGNUM;
+ }
+ }
+ else if (kind == eRegisterKindLLDB)
+ {
+ return num;
+ }
+ }
}
- }
- else if (kind == eRegisterKindLLDB)
- {
- return num;
}
return LLDB_INVALID_REGNUM;
@@ -788,26 +1019,26 @@ bool
RegisterContext_x86_64::ReadGPR()
{
ProcessMonitor &monitor = GetMonitor();
- return monitor.ReadGPR(m_thread.GetID(), &user.regs);
+ return monitor.ReadGPR(m_thread.GetID(), &user.regs, sizeof(user.regs));
}
bool
RegisterContext_x86_64::ReadFPR()
{
ProcessMonitor &monitor = GetMonitor();
- return monitor.ReadFPR(m_thread.GetID(), &user.i387);
+ return monitor.ReadFPR(m_thread.GetID(), &user.i387, sizeof(user.i387));
}
bool
RegisterContext_x86_64::WriteGPR()
{
ProcessMonitor &monitor = GetMonitor();
- return monitor.WriteGPR(m_thread.GetID(), &user.regs);
+ return monitor.WriteGPR(m_thread.GetID(), &user.regs, sizeof(user.regs));
}
bool
RegisterContext_x86_64::WriteFPR()
{
ProcessMonitor &monitor = GetMonitor();
- return monitor.WriteFPR(m_thread.GetID(), &user.i387);
+ return monitor.WriteFPR(m_thread.GetID(), &user.i387, sizeof(user.i387));
}
Modified: lldb/branches/windows/source/Plugins/Process/POSIX/RegisterContext_x86_64.h
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/windows/source/Plugins/Process/POSIX/RegisterContext_x86_64.h?rev=179679&r1=179678&r2=179679&view=diff
==============================================================================
--- lldb/branches/windows/source/Plugins/Process/POSIX/RegisterContext_x86_64.h (original)
+++ lldb/branches/windows/source/Plugins/Process/POSIX/RegisterContext_x86_64.h Wed Apr 17 03:38:48 2013
@@ -42,13 +42,13 @@ public:
GetRegisterCount();
const lldb_private::RegisterInfo *
- GetRegisterInfoAtIndex(uint32_t reg);
+ GetRegisterInfoAtIndex(size_t reg);
size_t
GetRegisterSetCount();
const lldb_private::RegisterSet *
- GetRegisterSet(uint32_t set);
+ GetRegisterSet(size_t set);
static unsigned
GetRegisterIndexFromOffset(unsigned offset);
@@ -128,6 +128,11 @@ public:
uint64_t fault_address; // Control register CR3.
};
+protected:
+ // Determines if an extended register set is supported on the processor running the inferior process.
+ virtual bool
+ IsRegisterSetAvailable(size_t set_index);
+
private:
UserArea user;
Modified: lldb/branches/windows/source/Plugins/Process/Utility/DynamicRegisterInfo.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/windows/source/Plugins/Process/Utility/DynamicRegisterInfo.cpp?rev=179679&r1=179678&r2=179679&view=diff
==============================================================================
--- lldb/branches/windows/source/Plugins/Process/Utility/DynamicRegisterInfo.cpp (original)
+++ lldb/branches/windows/source/Plugins/Process/Utility/DynamicRegisterInfo.cpp Wed Apr 17 03:38:48 2013
@@ -34,7 +34,7 @@ DynamicRegisterInfo::DynamicRegisterInfo
{
}
-DynamicRegisterInfo::DynamicRegisterInfo (const lldb_private::PythonDataDictionary &dict) :
+DynamicRegisterInfo::DynamicRegisterInfo (const lldb_private::PythonDictionary &dict) :
m_regs (),
m_sets (),
m_set_reg_nums (),
@@ -50,16 +50,19 @@ DynamicRegisterInfo::~DynamicRegisterInf
size_t
-DynamicRegisterInfo::SetRegisterInfo (const lldb_private::PythonDataDictionary &dict)
+DynamicRegisterInfo::SetRegisterInfo (const lldb_private::PythonDictionary &dict)
{
#ifndef LLDB_DISABLE_PYTHON
- PythonDataArray sets (dict.GetItemForKey("sets").GetArrayObject());
+ PythonList sets (dict.GetItemForKey("sets"));
if (sets)
{
const uint32_t num_sets = sets.GetSize();
for (uint32_t i=0; i<num_sets; ++i)
{
- ConstString set_name (sets.GetItemAtIndex(i).GetStringObject().GetString());
+ PythonString py_set_name(sets.GetItemAtIndex(i));
+ ConstString set_name;
+ if (py_set_name)
+ set_name.SetCString(py_set_name.GetString());
if (set_name)
{
RegisterSet new_set = { set_name.AsCString(), NULL, 0, NULL };
@@ -73,23 +76,23 @@ DynamicRegisterInfo::SetRegisterInfo (co
}
m_set_reg_nums.resize(m_sets.size());
}
- PythonDataArray regs (dict.GetItemForKey("registers").GetArrayObject());
+ PythonList regs (dict.GetItemForKey("registers"));
if (regs)
{
const uint32_t num_regs = regs.GetSize();
- PythonDataString name_pystr("name");
- PythonDataString altname_pystr("alt-name");
- PythonDataString bitsize_pystr("bitsize");
- PythonDataString offset_pystr("offset");
- PythonDataString encoding_pystr("encoding");
- PythonDataString format_pystr("format");
- PythonDataString set_pystr("set");
- PythonDataString gcc_pystr("gcc");
- PythonDataString dwarf_pystr("dwarf");
- PythonDataString generic_pystr("generic");
+ PythonString name_pystr("name");
+ PythonString altname_pystr("alt-name");
+ PythonString bitsize_pystr("bitsize");
+ PythonString offset_pystr("offset");
+ PythonString encoding_pystr("encoding");
+ PythonString format_pystr("format");
+ PythonString set_pystr("set");
+ PythonString gcc_pystr("gcc");
+ PythonString dwarf_pystr("dwarf");
+ PythonString generic_pystr("generic");
for (uint32_t i=0; i<num_regs; ++i)
{
- PythonDataDictionary reg_info_dict(regs.GetItemAtIndex(i).GetDictionaryObject());
+ PythonDictionary reg_info_dict(regs.GetItemAtIndex(i));
if (reg_info_dict)
{
// { 'name':'rcx' , 'bitsize' : 64, 'offset' : 16, 'encoding':'uint' , 'format':'hex' , 'set': 0, 'gcc' : 2, 'dwarf' : 2, 'generic':'arg4', 'alt-name':'arg4', },
Modified: lldb/branches/windows/source/Plugins/Process/Utility/DynamicRegisterInfo.h
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/windows/source/Plugins/Process/Utility/DynamicRegisterInfo.h?rev=179679&r1=179678&r2=179679&view=diff
==============================================================================
--- lldb/branches/windows/source/Plugins/Process/Utility/DynamicRegisterInfo.h (original)
+++ lldb/branches/windows/source/Plugins/Process/Utility/DynamicRegisterInfo.h Wed Apr 17 03:38:48 2013
@@ -24,13 +24,13 @@ class DynamicRegisterInfo
public:
DynamicRegisterInfo ();
- DynamicRegisterInfo (const lldb_private::PythonDataDictionary &dict);
+ DynamicRegisterInfo (const lldb_private::PythonDictionary &dict);
virtual
~DynamicRegisterInfo ();
size_t
- SetRegisterInfo (const lldb_private::PythonDataDictionary &dict);
+ SetRegisterInfo (const lldb_private::PythonDictionary &dict);
void
AddRegister (lldb_private::RegisterInfo ®_info,
Modified: lldb/branches/windows/source/Plugins/Process/Utility/InferiorCallPOSIX.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/windows/source/Plugins/Process/Utility/InferiorCallPOSIX.cpp?rev=179679&r1=179678&r2=179679&view=diff
==============================================================================
--- lldb/branches/windows/source/Plugins/Process/Utility/InferiorCallPOSIX.cpp (original)
+++ lldb/branches/windows/source/Plugins/Process/Utility/InferiorCallPOSIX.cpp Wed Apr 17 03:38:48 2013
@@ -8,6 +8,7 @@
//===----------------------------------------------------------------------===//
#include "InferiorCallPOSIX.h"
+#include "lldb/Core/Address.h"
#include "lldb/Core/StreamFile.h"
#include "lldb/Core/ValueObject.h"
#include "lldb/Symbol/ClangASTContext.h"
@@ -58,7 +59,8 @@ bool lldb_private::InferiorCallMmap(Proc
const uint32_t range_scope = eSymbolContextFunction | eSymbolContextSymbol;
const bool use_inline_block_range = false;
const bool stop_other_threads = true;
- const bool discard_on_error = true;
+ const bool unwind_on_error = true;
+ const bool ignore_breakpoints = true;
const bool try_all_threads = true;
const uint32_t timeout_usec = 500000;
@@ -90,7 +92,8 @@ bool lldb_private::InferiorCallMmap(Proc
mmap_range.GetBaseAddress(),
ClangASTType (clang_ast_context->getASTContext(), clang_void_ptr_type),
stop_other_threads,
- discard_on_error,
+ unwind_on_error,
+ ignore_breakpoints,
&addr,
&length,
&prot_arg,
@@ -114,7 +117,8 @@ bool lldb_private::InferiorCallMmap(Proc
call_plan_sp,
stop_other_threads,
try_all_threads,
- discard_on_error,
+ unwind_on_error,
+ ignore_breakpoints,
timeout_usec,
error_strm);
if (result == eExecutionCompleted)
@@ -126,6 +130,11 @@ bool lldb_private::InferiorCallMmap(Proc
if (allocated_addr == UINT32_MAX)
return false;
}
+ else if (process->GetAddressByteSize() == 8)
+ {
+ if (allocated_addr == UINT64_MAX)
+ return false;
+ }
return true;
}
}
@@ -162,7 +171,8 @@ bool lldb_private::InferiorCallMunmap(Pr
const uint32_t range_scope = eSymbolContextFunction | eSymbolContextSymbol;
const bool use_inline_block_range = false;
const bool stop_other_threads = true;
- const bool discard_on_error = true;
+ const bool unwind_on_error = true;
+ const bool ignore_breakpoints = true;
const bool try_all_threads = true;
const uint32_t timeout_usec = 500000;
@@ -173,7 +183,8 @@ bool lldb_private::InferiorCallMunmap(Pr
munmap_range.GetBaseAddress(),
ClangASTType(),
stop_other_threads,
- discard_on_error,
+ unwind_on_error,
+ ignore_breakpoints,
&addr,
&length));
if (call_plan_sp)
@@ -192,7 +203,8 @@ bool lldb_private::InferiorCallMunmap(Pr
call_plan_sp,
stop_other_threads,
try_all_threads,
- discard_on_error,
+ unwind_on_error,
+ ignore_breakpoints,
timeout_usec,
error_strm);
if (result == eExecutionCompleted)
@@ -207,3 +219,66 @@ bool lldb_private::InferiorCallMunmap(Pr
return false;
}
+
+bool lldb_private::InferiorCall(Process *process, const Address *address, addr_t &returned_func) {
+ Thread *thread = process->GetThreadList().GetSelectedThread().get();
+ if (thread == NULL || address == NULL)
+ return false;
+
+ const bool stop_other_threads = true;
+ const bool unwind_on_error = true;
+ const bool ignore_breakpoints = true;
+ const bool try_all_threads = true;
+ const uint32_t timeout_usec = 500000;
+
+ ClangASTContext *clang_ast_context = process->GetTarget().GetScratchClangASTContext();
+ lldb::clang_type_t clang_void_ptr_type = clang_ast_context->GetVoidPtrType(false);
+ ThreadPlanCallFunction *call_function_thread_plan
+ = new ThreadPlanCallFunction (*thread,
+ *address,
+ ClangASTType (clang_ast_context->getASTContext(), clang_void_ptr_type),
+ stop_other_threads,
+ unwind_on_error,
+ ignore_breakpoints);
+ lldb::ThreadPlanSP call_plan_sp (call_function_thread_plan);
+ if (call_plan_sp)
+ {
+ StreamFile error_strm;
+ // This plan is a utility plan, so set it to discard itself when done.
+ call_plan_sp->SetIsMasterPlan (true);
+ call_plan_sp->SetOkayToDiscard(true);
+
+ StackFrame *frame = thread->GetStackFrameAtIndex (0).get();
+ if (frame)
+ {
+ ExecutionContext exe_ctx;
+ frame->CalculateExecutionContext (exe_ctx);
+ ExecutionResults result = process->RunThreadPlan (exe_ctx,
+ call_plan_sp,
+ stop_other_threads,
+ try_all_threads,
+ unwind_on_error,
+ ignore_breakpoints,
+ timeout_usec,
+ error_strm);
+ if (result == eExecutionCompleted)
+ {
+ returned_func = call_plan_sp->GetReturnValueObject()->GetValueAsUnsigned(LLDB_INVALID_ADDRESS);
+
+ if (process->GetAddressByteSize() == 4)
+ {
+ if (returned_func == UINT32_MAX)
+ return false;
+ }
+ else if (process->GetAddressByteSize() == 8)
+ {
+ if (returned_func == UINT64_MAX)
+ return false;
+ }
+ return true;
+ }
+ }
+ }
+
+ return false;
+}
Modified: lldb/branches/windows/source/Plugins/Process/Utility/InferiorCallPOSIX.h
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/windows/source/Plugins/Process/Utility/InferiorCallPOSIX.h?rev=179679&r1=179678&r2=179679&view=diff
==============================================================================
--- lldb/branches/windows/source/Plugins/Process/Utility/InferiorCallPOSIX.h (original)
+++ lldb/branches/windows/source/Plugins/Process/Utility/InferiorCallPOSIX.h Wed Apr 17 03:38:48 2013
@@ -36,6 +36,8 @@ bool InferiorCallMmap(Process *proc, lld
bool InferiorCallMunmap(Process *proc, lldb::addr_t addr, lldb::addr_t length);
+bool InferiorCall(Process *proc, const Address *address, lldb::addr_t &returned_func);
+
} // namespace lldb_private
#endif // lldb_InferiorCallPOSIX_h_
Modified: lldb/branches/windows/source/Plugins/Process/Utility/RegisterContextDarwin_arm.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/windows/source/Plugins/Process/Utility/RegisterContextDarwin_arm.cpp?rev=179679&r1=179678&r2=179679&view=diff
==============================================================================
--- lldb/branches/windows/source/Plugins/Process/Utility/RegisterContextDarwin_arm.cpp (original)
+++ lldb/branches/windows/source/Plugins/Process/Utility/RegisterContextDarwin_arm.cpp Wed Apr 17 03:38:48 2013
@@ -416,7 +416,7 @@ RegisterContextDarwin_arm::GetRegisterCo
}
const RegisterInfo *
-RegisterContextDarwin_arm::GetRegisterInfoAtIndex (uint32_t reg)
+RegisterContextDarwin_arm::GetRegisterInfoAtIndex (size_t reg)
{
assert(k_num_register_infos == k_num_registers);
if (reg < k_num_registers)
@@ -464,7 +464,7 @@ RegisterContextDarwin_arm::GetRegisterSe
}
const RegisterSet *
-RegisterContextDarwin_arm::GetRegisterSet (uint32_t reg_set)
+RegisterContextDarwin_arm::GetRegisterSet (size_t reg_set)
{
if (reg_set < k_num_regsets)
return &g_reg_sets[reg_set];
Modified: lldb/branches/windows/source/Plugins/Process/Utility/RegisterContextDarwin_arm.h
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/windows/source/Plugins/Process/Utility/RegisterContextDarwin_arm.h?rev=179679&r1=179678&r2=179679&view=diff
==============================================================================
--- lldb/branches/windows/source/Plugins/Process/Utility/RegisterContextDarwin_arm.h (original)
+++ lldb/branches/windows/source/Plugins/Process/Utility/RegisterContextDarwin_arm.h Wed Apr 17 03:38:48 2013
@@ -64,13 +64,13 @@ public:
GetRegisterCount ();
virtual const lldb_private::RegisterInfo *
- GetRegisterInfoAtIndex (uint32_t reg);
+ GetRegisterInfoAtIndex (size_t reg);
virtual size_t
GetRegisterSetCount ();
virtual const lldb_private::RegisterSet *
- GetRegisterSet (uint32_t set);
+ GetRegisterSet (size_t set);
virtual bool
ReadRegister (const lldb_private::RegisterInfo *reg_info,
Modified: lldb/branches/windows/source/Plugins/Process/Utility/RegisterContextDarwin_i386.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/windows/source/Plugins/Process/Utility/RegisterContextDarwin_i386.cpp?rev=179679&r1=179678&r2=179679&view=diff
==============================================================================
--- lldb/branches/windows/source/Plugins/Process/Utility/RegisterContextDarwin_i386.cpp (original)
+++ lldb/branches/windows/source/Plugins/Process/Utility/RegisterContextDarwin_i386.cpp Wed Apr 17 03:38:48 2013
@@ -298,7 +298,7 @@ RegisterContextDarwin_i386::GetRegisterC
}
const RegisterInfo *
-RegisterContextDarwin_i386::GetRegisterInfoAtIndex (uint32_t reg)
+RegisterContextDarwin_i386::GetRegisterInfoAtIndex (size_t reg)
{
assert(k_num_register_infos == k_num_registers);
if (reg < k_num_registers)
@@ -410,7 +410,7 @@ RegisterContextDarwin_i386::GetRegisterS
}
const RegisterSet *
-RegisterContextDarwin_i386::GetRegisterSet (uint32_t reg_set)
+RegisterContextDarwin_i386::GetRegisterSet (size_t reg_set)
{
if (reg_set < k_num_regsets)
return &g_reg_sets[reg_set];
Modified: lldb/branches/windows/source/Plugins/Process/Utility/RegisterContextDarwin_i386.h
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/windows/source/Plugins/Process/Utility/RegisterContextDarwin_i386.h?rev=179679&r1=179678&r2=179679&view=diff
==============================================================================
--- lldb/branches/windows/source/Plugins/Process/Utility/RegisterContextDarwin_i386.h (original)
+++ lldb/branches/windows/source/Plugins/Process/Utility/RegisterContextDarwin_i386.h Wed Apr 17 03:38:48 2013
@@ -34,13 +34,13 @@ public:
GetRegisterCount ();
virtual const lldb_private::RegisterInfo *
- GetRegisterInfoAtIndex (uint32_t reg);
+ GetRegisterInfoAtIndex (size_t reg);
virtual size_t
GetRegisterSetCount ();
virtual const lldb_private::RegisterSet *
- GetRegisterSet (uint32_t set);
+ GetRegisterSet (size_t set);
virtual bool
ReadRegister (const lldb_private::RegisterInfo *reg_info, lldb_private::RegisterValue &value);
Modified: lldb/branches/windows/source/Plugins/Process/Utility/RegisterContextDarwin_x86_64.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/windows/source/Plugins/Process/Utility/RegisterContextDarwin_x86_64.cpp?rev=179679&r1=179678&r2=179679&view=diff
==============================================================================
--- lldb/branches/windows/source/Plugins/Process/Utility/RegisterContextDarwin_x86_64.cpp (original)
+++ lldb/branches/windows/source/Plugins/Process/Utility/RegisterContextDarwin_x86_64.cpp Wed Apr 17 03:38:48 2013
@@ -336,7 +336,7 @@ RegisterContextDarwin_x86_64::GetRegiste
const RegisterInfo *
-RegisterContextDarwin_x86_64::GetRegisterInfoAtIndex (uint32_t reg)
+RegisterContextDarwin_x86_64::GetRegisterInfoAtIndex (size_t reg)
{
assert(k_num_register_infos == k_num_registers);
if (reg < k_num_registers)
@@ -457,7 +457,7 @@ RegisterContextDarwin_x86_64::GetRegiste
}
const RegisterSet *
-RegisterContextDarwin_x86_64::GetRegisterSet (uint32_t reg_set)
+RegisterContextDarwin_x86_64::GetRegisterSet (size_t reg_set)
{
if (reg_set < k_num_regsets)
return &g_reg_sets[reg_set];
Modified: lldb/branches/windows/source/Plugins/Process/Utility/RegisterContextDarwin_x86_64.h
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/windows/source/Plugins/Process/Utility/RegisterContextDarwin_x86_64.h?rev=179679&r1=179678&r2=179679&view=diff
==============================================================================
--- lldb/branches/windows/source/Plugins/Process/Utility/RegisterContextDarwin_x86_64.h (original)
+++ lldb/branches/windows/source/Plugins/Process/Utility/RegisterContextDarwin_x86_64.h Wed Apr 17 03:38:48 2013
@@ -33,13 +33,13 @@ public:
GetRegisterCount ();
virtual const lldb_private::RegisterInfo *
- GetRegisterInfoAtIndex (uint32_t reg);
+ GetRegisterInfoAtIndex (size_t reg);
virtual size_t
GetRegisterSetCount ();
virtual const lldb_private::RegisterSet *
- GetRegisterSet (uint32_t set);
+ GetRegisterSet (size_t set);
virtual bool
ReadRegister (const lldb_private::RegisterInfo *reg_info, lldb_private::RegisterValue &value);
Modified: lldb/branches/windows/source/Plugins/Process/Utility/RegisterContextLLDB.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/windows/source/Plugins/Process/Utility/RegisterContextLLDB.cpp?rev=179679&r1=179678&r2=179679&view=diff
==============================================================================
--- lldb/branches/windows/source/Plugins/Process/Utility/RegisterContextLLDB.cpp (original)
+++ lldb/branches/windows/source/Plugins/Process/Utility/RegisterContextLLDB.cpp Wed Apr 17 03:38:48 2013
@@ -60,7 +60,7 @@ RegisterContextLLDB::RegisterContextLLDB
m_registers(),
m_parent_unwind (unwind_lldb)
{
- m_sym_ctx.Clear();
+ m_sym_ctx.Clear(false);
m_sym_ctx_valid = false;
if (IsFrameZero ())
@@ -87,7 +87,7 @@ RegisterContextLLDB::RegisterContextLLDB
void
RegisterContextLLDB::InitializeZerothFrame()
{
- LogSP log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_UNWIND));
+ Log *log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_UNWIND));
ExecutionContext exe_ctx(m_thread.shared_from_this());
RegisterContextSP reg_ctx_sp = m_thread.GetRegisterContext();
@@ -186,7 +186,7 @@ RegisterContextLLDB::InitializeZerothFra
{
active_row = m_full_unwind_plan_sp->GetRowForFunctionOffset (m_current_offset);
row_register_kind = m_full_unwind_plan_sp->GetRegisterKind ();
- LogSP log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_UNWIND));
+ Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_UNWIND));
if (active_row.get() && log)
{
StreamString active_row_strm;
@@ -228,7 +228,7 @@ RegisterContextLLDB::InitializeZerothFra
void
RegisterContextLLDB::InitializeNonZerothFrame()
{
- LogSP log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_UNWIND));
+ Log *log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_UNWIND));
if (IsFrameZero ())
{
m_frame_type = eNotAValidFrame;
@@ -410,7 +410,7 @@ RegisterContextLLDB::InitializeNonZeroth
{
Address temporary_pc(m_current_pc);
temporary_pc.SetOffset(m_current_pc.GetOffset() - 1);
- m_sym_ctx.Clear();
+ m_sym_ctx.Clear(false);
m_sym_ctx_valid = false;
if ((pc_module_sp->ResolveSymbolContextForAddress (temporary_pc, eSymbolContextFunction| eSymbolContextSymbol, m_sym_ctx) & eSymbolContextSymbol) == eSymbolContextSymbol)
{
@@ -592,7 +592,7 @@ RegisterContextLLDB::GetFastUnwindPlanFo
{
if (unwind_plan_sp->PlanValidAtAddress (m_current_pc))
{
- LogSP log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_UNWIND));
+ Log *log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_UNWIND));
if (log && log->GetVerbose())
{
if (m_fast_unwind_plan_sp)
@@ -761,7 +761,7 @@ RegisterContextLLDB::GetRegisterCount ()
}
const RegisterInfo *
-RegisterContextLLDB::GetRegisterInfoAtIndex (uint32_t reg)
+RegisterContextLLDB::GetRegisterInfoAtIndex (size_t reg)
{
return m_thread.GetRegisterContext()->GetRegisterInfoAtIndex (reg);
}
@@ -773,7 +773,7 @@ RegisterContextLLDB::GetRegisterSetCount
}
const RegisterSet *
-RegisterContextLLDB::GetRegisterSet (uint32_t reg_set)
+RegisterContextLLDB::GetRegisterSet (size_t reg_set)
{
return m_thread.GetRegisterContext()->GetRegisterSet (reg_set);
}
@@ -979,12 +979,14 @@ RegisterContextLLDB::SavedLocationForReg
UnwindPlan::RowSP active_row = m_full_unwind_plan_sp->GetRowForFunctionOffset (m_current_offset);
unwindplan_registerkind = m_full_unwind_plan_sp->GetRegisterKind ();
uint32_t row_regnum;
+ bool row_register_rewritten_to_return_address_reg = false;
// If we're fetching the saved pc and this UnwindPlan defines a ReturnAddress register (e.g. lr on arm),
// look for the return address register number in the UnwindPlan's row.
if (lldb_regnum == pc_regnum && m_full_unwind_plan_sp->GetReturnAddressRegister() != LLDB_INVALID_REGNUM)
{
row_regnum = m_full_unwind_plan_sp->GetReturnAddressRegister();
+ row_register_rewritten_to_return_address_reg = true;
UnwindLogMsg ("requested caller's saved PC but this UnwindPlan uses a RA reg; getting reg %d instead",
row_regnum);
}
@@ -1008,6 +1010,28 @@ RegisterContextLLDB::SavedLocationForReg
m_full_unwind_plan_sp->GetSourceName().GetCString());
}
+ // This is frame 0 and we're retrieving the PC and it's saved in a Return Address register and
+ // it hasn't been saved anywhere yet -- that is, it's still live in the actual register.
+ // Handle this specially.
+
+ if (have_unwindplan_regloc == false
+ && row_register_rewritten_to_return_address_reg == true
+ && IsFrameZero()
+ && row_regnum != LLDB_INVALID_REGNUM)
+ {
+ uint32_t ra_regnum_in_lldb_reg_numbering;
+ if (m_thread.GetRegisterContext()->ConvertBetweenRegisterKinds (unwindplan_registerkind, row_regnum, eRegisterKindLLDB, ra_regnum_in_lldb_reg_numbering))
+ {
+ lldb_private::UnwindLLDB::RegisterLocation new_regloc;
+ new_regloc.type = UnwindLLDB::RegisterLocation::eRegisterInRegister;
+ new_regloc.location.register_number = ra_regnum_in_lldb_reg_numbering;
+ m_registers[lldb_regnum] = new_regloc;
+ regloc = new_regloc;
+ UnwindLogMsg ("supplying caller's register %d from the live RegisterContext at frame 0, saved in %d", lldb_regnum, ra_regnum_in_lldb_reg_numbering);
+ return UnwindLLDB::RegisterSearchResult::eRegisterFound;
+ }
+ }
+
// If this architecture stores the return address in a register (it defines a Return Address register)
// and we're on a non-zero stack frame and the Full UnwindPlan says that the pc is stored in the
// RA registers (e.g. lr on arm), then we know that the full unwindplan is not trustworthy -- this
@@ -1457,7 +1481,7 @@ RegisterContextLLDB::ReadPC (addr_t& pc)
void
RegisterContextLLDB::UnwindLogMsg (const char *fmt, ...)
{
- LogSP log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_UNWIND));
+ Log *log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_UNWIND));
if (log)
{
va_list args;
@@ -1483,7 +1507,7 @@ RegisterContextLLDB::UnwindLogMsg (const
void
RegisterContextLLDB::UnwindLogMsgVerbose (const char *fmt, ...)
{
- LogSP log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_UNWIND));
+ Log *log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_UNWIND));
if (log && log->GetVerbose())
{
va_list args;
Modified: lldb/branches/windows/source/Plugins/Process/Utility/RegisterContextLLDB.h
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/windows/source/Plugins/Process/Utility/RegisterContextLLDB.h?rev=179679&r1=179678&r2=179679&view=diff
==============================================================================
--- lldb/branches/windows/source/Plugins/Process/Utility/RegisterContextLLDB.h (original)
+++ lldb/branches/windows/source/Plugins/Process/Utility/RegisterContextLLDB.h Wed Apr 17 03:38:48 2013
@@ -46,13 +46,13 @@ public:
GetRegisterCount ();
virtual const lldb_private::RegisterInfo *
- GetRegisterInfoAtIndex (uint32_t reg);
+ GetRegisterInfoAtIndex (size_t reg);
virtual size_t
GetRegisterSetCount ();
virtual const lldb_private::RegisterSet *
- GetRegisterSet (uint32_t reg_set);
+ GetRegisterSet (size_t reg_set);
virtual bool
ReadRegister (const lldb_private::RegisterInfo *reg_info, lldb_private::RegisterValue &value);
Modified: lldb/branches/windows/source/Plugins/Process/Utility/RegisterContextMacOSXFrameBackchain.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/windows/source/Plugins/Process/Utility/RegisterContextMacOSXFrameBackchain.cpp?rev=179679&r1=179678&r2=179679&view=diff
==============================================================================
--- lldb/branches/windows/source/Plugins/Process/Utility/RegisterContextMacOSXFrameBackchain.cpp (original)
+++ lldb/branches/windows/source/Plugins/Process/Utility/RegisterContextMacOSXFrameBackchain.cpp Wed Apr 17 03:38:48 2013
@@ -59,7 +59,7 @@ RegisterContextMacOSXFrameBackchain::Get
}
const RegisterInfo *
-RegisterContextMacOSXFrameBackchain::GetRegisterInfoAtIndex (uint32_t reg)
+RegisterContextMacOSXFrameBackchain::GetRegisterInfoAtIndex (size_t reg)
{
return m_thread.GetRegisterContext()->GetRegisterInfoAtIndex(reg);
}
@@ -73,7 +73,7 @@ RegisterContextMacOSXFrameBackchain::Get
const RegisterSet *
-RegisterContextMacOSXFrameBackchain::GetRegisterSet (uint32_t reg_set)
+RegisterContextMacOSXFrameBackchain::GetRegisterSet (size_t reg_set)
{
return m_thread.GetRegisterContext()->GetRegisterSet (reg_set);
}
Modified: lldb/branches/windows/source/Plugins/Process/Utility/RegisterContextMacOSXFrameBackchain.h
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/windows/source/Plugins/Process/Utility/RegisterContextMacOSXFrameBackchain.h?rev=179679&r1=179678&r2=179679&view=diff
==============================================================================
--- lldb/branches/windows/source/Plugins/Process/Utility/RegisterContextMacOSXFrameBackchain.h (original)
+++ lldb/branches/windows/source/Plugins/Process/Utility/RegisterContextMacOSXFrameBackchain.h Wed Apr 17 03:38:48 2013
@@ -42,13 +42,13 @@ public:
GetRegisterCount ();
virtual const lldb_private::RegisterInfo *
- GetRegisterInfoAtIndex (uint32_t reg);
+ GetRegisterInfoAtIndex (size_t reg);
virtual size_t
GetRegisterSetCount ();
virtual const lldb_private::RegisterSet *
- GetRegisterSet (uint32_t reg_set);
+ GetRegisterSet (size_t reg_set);
virtual bool
ReadRegister (const lldb_private::RegisterInfo *reg_info, lldb_private::RegisterValue &value);
Modified: lldb/branches/windows/source/Plugins/Process/Utility/RegisterContextMemory.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/windows/source/Plugins/Process/Utility/RegisterContextMemory.cpp?rev=179679&r1=179678&r2=179679&view=diff
==============================================================================
--- lldb/branches/windows/source/Plugins/Process/Utility/RegisterContextMemory.cpp (original)
+++ lldb/branches/windows/source/Plugins/Process/Utility/RegisterContextMemory.cpp Wed Apr 17 03:38:48 2013
@@ -80,7 +80,7 @@ RegisterContextMemory::GetRegisterCount
}
const RegisterInfo *
-RegisterContextMemory::GetRegisterInfoAtIndex (uint32_t reg)
+RegisterContextMemory::GetRegisterInfoAtIndex (size_t reg)
{
return m_reg_infos.GetRegisterInfoAtIndex (reg);
}
@@ -92,7 +92,7 @@ RegisterContextMemory::GetRegisterSetCou
}
const RegisterSet *
-RegisterContextMemory::GetRegisterSet (uint32_t reg_set)
+RegisterContextMemory::GetRegisterSet (size_t reg_set)
{
return m_reg_infos.GetRegisterSet (reg_set);
}
Modified: lldb/branches/windows/source/Plugins/Process/Utility/RegisterContextMemory.h
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/windows/source/Plugins/Process/Utility/RegisterContextMemory.h?rev=179679&r1=179678&r2=179679&view=diff
==============================================================================
--- lldb/branches/windows/source/Plugins/Process/Utility/RegisterContextMemory.h (original)
+++ lldb/branches/windows/source/Plugins/Process/Utility/RegisterContextMemory.h Wed Apr 17 03:38:48 2013
@@ -46,13 +46,13 @@ public:
GetRegisterCount ();
virtual const lldb_private::RegisterInfo *
- GetRegisterInfoAtIndex (uint32_t reg);
+ GetRegisterInfoAtIndex (size_t reg);
virtual size_t
GetRegisterSetCount ();
virtual const lldb_private::RegisterSet *
- GetRegisterSet (uint32_t reg_set);
+ GetRegisterSet (size_t reg_set);
virtual uint32_t
ConvertRegisterKindToRegisterNumber (uint32_t kind, uint32_t num);
@@ -60,7 +60,7 @@ public:
//------------------------------------------------------------------
// If all of the thread register are in a contiguous buffer in
- // memory, then the default ReadRegister/WriteRegiter and
+ // memory, then the default ReadRegister/WriteRegister and
// ReadAllRegisterValues/WriteAllRegisterValues will work. If thread
// registers are not contiguous, clients will want to subclass this
// class and modify the read/write functions as needed.
Modified: lldb/branches/windows/source/Plugins/Process/Utility/StopInfoMachException.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/windows/source/Plugins/Process/Utility/StopInfoMachException.cpp?rev=179679&r1=179678&r2=179679&view=diff
==============================================================================
--- lldb/branches/windows/source/Plugins/Process/Utility/StopInfoMachException.cpp (original)
+++ lldb/branches/windows/source/Plugins/Process/Utility/StopInfoMachException.cpp Wed Apr 17 03:38:48 2013
@@ -49,7 +49,14 @@ StopInfoMachException::GetDescription ()
exc_desc = "EXC_BAD_ACCESS";
subcode_label = "address";
switch (cpu)
- {
+ {
+ case llvm::Triple::x86:
+ case llvm::Triple::x86_64:
+ switch (m_exc_code)
+ {
+ case 0xd: code_desc = "EXC_I386_GPFLT"; m_exc_data_count = 1; break;
+ }
+ break;
case llvm::Triple::arm:
switch (m_exc_code)
{
@@ -210,6 +217,12 @@ StopInfoMachException::GetDescription ()
case 10:
exc_desc = "EXC_CRASH";
break;
+ case 11:
+ exc_desc = "EXC_RESOURCE";
+ break;
+ case 12:
+ exc_desc = "EXC_GUARD";
+ break;
}
StreamString strm;
@@ -339,8 +352,8 @@ StopInfoMachException::CreateStopReasonW
case 6: // EXC_BREAKPOINT
{
- bool is_software_breakpoint = false;
- bool is_trace_if_software_breakpoint_missing = false;
+ bool is_actual_breakpoint = false;
+ bool is_trace_if_actual_breakpoint_missing = false;
switch (cpu)
{
case llvm::Triple::x86:
@@ -369,9 +382,9 @@ StopInfoMachException::CreateStopReasonW
{
// KDP returns EXC_I386_BPTFLT for trace breakpoints
if (exc_code == 3)
- is_trace_if_software_breakpoint_missing = true;
+ is_trace_if_actual_breakpoint_missing = true;
- is_software_breakpoint = true;
+ is_actual_breakpoint = true;
if (!pc_already_adjusted)
pc_decrement = 1;
}
@@ -379,11 +392,11 @@ StopInfoMachException::CreateStopReasonW
case llvm::Triple::ppc:
case llvm::Triple::ppc64:
- is_software_breakpoint = exc_code == 1; // EXC_PPC_BREAKPOINT
+ is_actual_breakpoint = exc_code == 1; // EXC_PPC_BREAKPOINT
break;
case llvm::Triple::arm:
- if (exc_code == 0x102)
+ if (exc_code == 0x102) // EXC_ARM_DA_DEBUG
{
// It's a watchpoint, then, if the exc_sub_code indicates a known/enabled
// data break address from our watchpoint list.
@@ -402,10 +415,10 @@ StopInfoMachException::CreateStopReasonW
if (thread.GetTemporaryResumeState() == eStateStepping)
return StopInfo::CreateStopReasonToTrace(thread);
}
- else if (exc_code == 1)
+ else if (exc_code == 1) // EXC_ARM_BREAKPOINT
{
- is_software_breakpoint = true;
- is_trace_if_software_breakpoint_missing = true;
+ is_actual_breakpoint = true;
+ is_trace_if_actual_breakpoint_missing = true;
}
break;
@@ -413,7 +426,7 @@ StopInfoMachException::CreateStopReasonW
break;
}
- if (is_software_breakpoint)
+ if (is_actual_breakpoint)
{
RegisterContextSP reg_ctx_sp (thread.GetRegisterContext());
addr_t pc = reg_ctx_sp->GetPC() - pc_decrement;
@@ -441,7 +454,7 @@ StopInfoMachException::CreateStopReasonW
}
// Don't call this a trace if we weren't single stepping this thread.
- if (is_trace_if_software_breakpoint_missing && thread.GetTemporaryResumeState() == eStateStepping)
+ if (is_trace_if_actual_breakpoint_missing && thread.GetTemporaryResumeState() == eStateStepping)
{
return StopInfo::CreateStopReasonToTrace (thread);
}
Modified: lldb/branches/windows/source/Plugins/Process/Utility/ThreadMemory.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/windows/source/Plugins/Process/Utility/ThreadMemory.cpp?rev=179679&r1=179678&r2=179679&view=diff
==============================================================================
--- lldb/branches/windows/source/Plugins/Process/Utility/ThreadMemory.cpp (original)
+++ lldb/branches/windows/source/Plugins/Process/Utility/ThreadMemory.cpp Wed Apr 17 03:38:48 2013
@@ -21,6 +21,7 @@ ThreadMemory::ThreadMemory (Process &pro
tid_t tid,
const ValueObjectSP &thread_info_valobj_sp) :
Thread (process, tid),
+ m_backing_thread_sp (),
m_thread_info_valobj_sp (thread_info_valobj_sp),
m_name(),
m_queue()
@@ -34,6 +35,7 @@ ThreadMemory::ThreadMemory (Process &pro
const char *queue,
lldb::addr_t register_data_addr) :
Thread (process, tid),
+ m_backing_thread_sp (),
m_thread_info_valobj_sp (),
m_name(),
m_queue(),
@@ -65,6 +67,9 @@ ThreadMemory::WillResume (StateType resu
RegisterContextSP
ThreadMemory::GetRegisterContext ()
{
+ if (m_backing_thread_sp)
+ return m_backing_thread_sp->GetRegisterContext();
+
if (!m_reg_context_sp)
{
ProcessSP process_sp (GetProcess());
@@ -81,6 +86,9 @@ ThreadMemory::GetRegisterContext ()
RegisterContextSP
ThreadMemory::CreateRegisterContextForFrame (StackFrame *frame)
{
+ if (m_backing_thread_sp)
+ return m_backing_thread_sp->CreateRegisterContextForFrame(frame);
+
RegisterContextSP reg_ctx_sp;
uint32_t concrete_frame_idx = 0;
@@ -91,9 +99,11 @@ ThreadMemory::CreateRegisterContextForFr
{
reg_ctx_sp = GetRegisterContext ();
}
- else if (m_unwinder_ap.get())
+ else
{
- reg_ctx_sp = m_unwinder_ap->CreateRegisterContextForFrame (frame);
+ Unwind *unwinder = GetUnwinder ();
+ if (unwinder)
+ reg_ctx_sp = unwinder->CreateRegisterContextForFrame (frame);
}
return reg_ctx_sp;
}
@@ -101,6 +111,9 @@ ThreadMemory::CreateRegisterContextForFr
lldb::StopInfoSP
ThreadMemory::GetPrivateStopReason ()
{
+ if (m_backing_thread_sp)
+ return m_backing_thread_sp->GetPrivateStopReason();
+
ProcessSP process_sp (GetProcess());
if (process_sp)
@@ -135,7 +148,14 @@ ThreadMemory::GetPrivateStopReason ()
void
ThreadMemory::RefreshStateAfterStop()
{
- RegisterContextSP reg_ctx_sp(GetRegisterContext());
+ if (m_backing_thread_sp)
+ return m_backing_thread_sp->RefreshStateAfterStop();
+
+
+ // Don't fetch the registers by calling Thread::GetRegisterContext() below.
+ // We might not have fetched any registers yet and we don't want to fetch
+ // the registers just to call invalidate on them...
+ RegisterContextSP reg_ctx_sp(m_reg_context_sp);
if (reg_ctx_sp)
{
const bool force = true;
Modified: lldb/branches/windows/source/Plugins/Process/Utility/ThreadMemory.h
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/windows/source/Plugins/Process/Utility/ThreadMemory.h?rev=179679&r1=179678&r2=179679&view=diff
==============================================================================
--- lldb/branches/windows/source/Plugins/Process/Utility/ThreadMemory.h (original)
+++ lldb/branches/windows/source/Plugins/Process/Utility/ThreadMemory.h Wed Apr 17 03:38:48 2013
@@ -33,9 +33,6 @@ public:
//------------------------------------------------------------------
// lldb_private::Thread methods
//------------------------------------------------------------------
- virtual void
- RefreshStateAfterStop();
-
virtual lldb::RegisterContextSP
GetRegisterContext ();
@@ -46,30 +43,75 @@ public:
GetPrivateStopReason ();
virtual const char *
+ GetInfo ()
+ {
+ if (m_backing_thread_sp)
+ m_backing_thread_sp->GetInfo();
+ return NULL;
+ }
+
+ virtual const char *
GetName ()
{
- return m_name.c_str();
+ if (!m_name.empty())
+ return m_name.c_str();
+ if (m_backing_thread_sp)
+ m_backing_thread_sp->GetName();
+ return NULL;
}
virtual const char *
GetQueueName ()
{
- return m_queue.c_str();
+ if (!m_queue.empty())
+ return m_queue.c_str();
+ if (m_backing_thread_sp)
+ m_backing_thread_sp->GetQueueName();
+ return NULL;
}
virtual bool
WillResume (lldb::StateType resume_state);
+ virtual void
+ DidResume ()
+ {
+ if (m_backing_thread_sp)
+ m_backing_thread_sp->DidResume();
+ }
+
+ virtual void
+ RefreshStateAfterStop();
+
lldb::ValueObjectSP &
GetValueObject ()
{
return m_thread_info_valobj_sp;
}
+
+ virtual void
+ ClearBackingThread ()
+ {
+ m_backing_thread_sp.reset();
+ }
+
+ virtual bool
+ SetBackingThread (const lldb::ThreadSP &thread_sp)
+ {
+ m_backing_thread_sp = thread_sp;
+ return (bool)thread_sp;
+ }
protected:
//------------------------------------------------------------------
// For ThreadMemory and subclasses
//------------------------------------------------------------------
+ // If this memory thread is actually represented by a thread from the
+ // lldb_private::Process subclass, then fill in the thread here and
+ // all APIs will be routed through this thread object. If m_backing_thread_sp
+ // is empty, then this thread is simply in memory with no representation
+ // through the process plug-in.
+ lldb::ThreadSP m_backing_thread_sp;
lldb::ValueObjectSP m_thread_info_valobj_sp;
std::string m_name;
std::string m_queue;
Modified: lldb/branches/windows/source/Plugins/Process/Utility/UnwindLLDB.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/windows/source/Plugins/Process/Utility/UnwindLLDB.cpp?rev=179679&r1=179678&r2=179679&view=diff
==============================================================================
--- lldb/branches/windows/source/Plugins/Process/Utility/UnwindLLDB.cpp (original)
+++ lldb/branches/windows/source/Plugins/Process/Utility/UnwindLLDB.cpp Wed Apr 17 03:38:48 2013
@@ -108,7 +108,7 @@ UnwindLLDB::AddOneMoreFrame (ABI *abi)
if (m_unwind_complete)
return false;
- LogSP log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_UNWIND));
+ Log *log(GetLogIfAllCategoriesSet (LIBLLDB_LOG_UNWIND));
CursorSP cursor_sp(new Cursor ());
// Frame zero is a little different
@@ -283,6 +283,19 @@ UnwindLLDB::SearchForSavedLocationForReg
{
UnwindLLDB::RegisterSearchResult result;
result = m_frames[frame_num]->reg_ctx_lldb_sp->SavedLocationForRegister (lldb_regnum, regloc);
+
+ // If we have unwind instructions saying that register N is saved in register M in the middle of
+ // the stack (and N can equal M here, meaning the register was not used in this function), then
+ // change the register number we're looking for to M and keep looking for a concrete location
+ // down the stack, or an actual value from a live RegisterContext at frame 0.
+ if (result == UnwindLLDB::RegisterSearchResult::eRegisterFound
+ && regloc.type == UnwindLLDB::RegisterLocation::eRegisterInRegister
+ && frame_num > 0)
+ {
+ result = UnwindLLDB::RegisterSearchResult::eRegisterNotFound;
+ lldb_regnum = regloc.location.register_number;
+ }
+
if (result == UnwindLLDB::RegisterSearchResult::eRegisterFound)
return true;
if (result == UnwindLLDB::RegisterSearchResult::eRegisterIsVolatile)
Modified: lldb/branches/windows/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/windows/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.cpp?rev=179679&r1=179678&r2=179679&view=diff
==============================================================================
--- lldb/branches/windows/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.cpp (original)
+++ lldb/branches/windows/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.cpp Wed Apr 17 03:38:48 2013
@@ -171,7 +171,7 @@ GDBRemoteCommunication::CalculcateChecks
size_t
GDBRemoteCommunication::SendAck ()
{
- LogSP log (ProcessGDBRemoteLog::GetLogIfAllCategoriesSet (GDBR_LOG_PACKETS));
+ Log *log (ProcessGDBRemoteLog::GetLogIfAllCategoriesSet (GDBR_LOG_PACKETS));
ConnectionStatus status = eConnectionStatusSuccess;
char ch = '+';
const size_t bytes_written = Write (&ch, 1, status, NULL);
@@ -184,7 +184,7 @@ GDBRemoteCommunication::SendAck ()
size_t
GDBRemoteCommunication::SendNack ()
{
- LogSP log (ProcessGDBRemoteLog::GetLogIfAllCategoriesSet (GDBR_LOG_PACKETS));
+ Log *log (ProcessGDBRemoteLog::GetLogIfAllCategoriesSet (GDBR_LOG_PACKETS));
ConnectionStatus status = eConnectionStatusSuccess;
char ch = '-';
const size_t bytes_written = Write (&ch, 1, status, NULL);
@@ -213,7 +213,7 @@ GDBRemoteCommunication::SendPacketNoLock
packet.PutChar('#');
packet.PutHex8(CalculcateChecksum (payload, payload_length));
- LogSP log (ProcessGDBRemoteLog::GetLogIfAllCategoriesSet (GDBR_LOG_PACKETS));
+ Log *log (ProcessGDBRemoteLog::GetLogIfAllCategoriesSet (GDBR_LOG_PACKETS));
ConnectionStatus status = eConnectionStatusSuccess;
size_t bytes_written = Write (packet.GetData(), packet.GetSize(), status, NULL);
if (log)
@@ -223,7 +223,7 @@ GDBRemoteCommunication::SendPacketNoLock
// logs all of the packet will set a boolean so that we don't dump this more
// than once
if (!m_history.DidDumpToLog ())
- m_history.Dump (log.get());
+ m_history.Dump (log);
log->Printf ("<%4zu> send packet: %.*s", bytes_written, (int)packet.GetSize(), packet.GetData());
}
@@ -285,7 +285,7 @@ GDBRemoteCommunication::WaitForPacketWit
uint8_t buffer[8192];
Error error;
- LogSP log (ProcessGDBRemoteLog::GetLogIfAllCategoriesSet (GDBR_LOG_PACKETS | GDBR_LOG_VERBOSE));
+ Log *log (ProcessGDBRemoteLog::GetLogIfAllCategoriesSet (GDBR_LOG_PACKETS | GDBR_LOG_VERBOSE));
// Check for a packet from our cache first without trying any reading...
if (CheckForPacket (NULL, 0, packet))
@@ -340,7 +340,7 @@ GDBRemoteCommunication::CheckForPacket (
// Put the packet data into the buffer in a thread safe fashion
Mutex::Locker locker(m_bytes_mutex);
- LogSP log (ProcessGDBRemoteLog::GetLogIfAllCategoriesSet (GDBR_LOG_PACKETS));
+ Log *log (ProcessGDBRemoteLog::GetLogIfAllCategoriesSet (GDBR_LOG_PACKETS));
if (src && src_len > 0)
{
@@ -457,7 +457,7 @@ GDBRemoteCommunication::CheckForPacket (
// logs all of the packet will set a boolean so that we don't dump this more
// than once
if (!m_history.DidDumpToLog ())
- m_history.Dump (log.get());
+ m_history.Dump (log);
log->Printf ("<%4zu> read packet: %.*s", total_length, (int)(total_length), m_bytes.c_str());
}
Modified: lldb/branches/windows/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/windows/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp?rev=179679&r1=179678&r2=179679&view=diff
==============================================================================
--- lldb/branches/windows/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp (original)
+++ lldb/branches/windows/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp Wed Apr 17 03:38:48 2013
@@ -12,6 +12,8 @@
// C Includes
// C++ Includes
+#include <sstream>
+
// Other libraries and framework includes
#include "llvm/ADT/Triple.h"
#include "lldb/Interpreter/Args.h"
@@ -75,6 +77,7 @@ GDBRemoteCommunicationClient::GDBRemoteC
m_async_packet (),
m_async_response (),
m_async_signal (-1),
+ m_thread_id_to_used_usec_map (),
m_host_arch(),
m_process_arch(),
m_os_version_major (UINT32_MAX),
@@ -312,7 +315,7 @@ GDBRemoteCommunicationClient::SendPacket
)
{
Mutex::Locker locker;
- LogSP log (ProcessGDBRemoteLog::GetLogIfAllCategoriesSet (GDBR_LOG_PROCESS));
+ Log *log (ProcessGDBRemoteLog::GetLogIfAllCategoriesSet (GDBR_LOG_PROCESS));
size_t response_len = 0;
if (GetSequenceMutex (locker))
{
@@ -425,6 +428,99 @@ GDBRemoteCommunicationClient::SendPacket
return response_len;
}
+static const char *end_delimiter = "--end--;";
+static const int end_delimiter_len = 8;
+
+std::string
+GDBRemoteCommunicationClient::HarmonizeThreadIdsForProfileData
+( ProcessGDBRemote *process,
+ StringExtractorGDBRemote& profileDataExtractor
+)
+{
+ std::map<uint64_t, uint32_t> new_thread_id_to_used_usec_map;
+ std::stringstream final_output;
+ std::string name, value;
+
+ // Going to assuming thread_used_usec comes first, else bail out.
+ while (profileDataExtractor.GetNameColonValue(name, value))
+ {
+ if (name.compare("thread_used_id") == 0)
+ {
+ StringExtractor threadIDHexExtractor(value.c_str());
+ uint64_t thread_id = threadIDHexExtractor.GetHexMaxU64(false, 0);
+
+ bool has_used_usec = false;
+ uint32_t curr_used_usec = 0;
+ std::string usec_name, usec_value;
+ uint32_t input_file_pos = profileDataExtractor.GetFilePos();
+ if (profileDataExtractor.GetNameColonValue(usec_name, usec_value))
+ {
+ if (usec_name.compare("thread_used_usec") == 0)
+ {
+ has_used_usec = true;
+ curr_used_usec = strtoull(usec_value.c_str(), NULL, 0);
+ }
+ else
+ {
+ // We didn't find what we want, it is probably
+ // an older version. Bail out.
+ profileDataExtractor.SetFilePos(input_file_pos);
+ }
+ }
+
+ if (has_used_usec)
+ {
+ uint32_t prev_used_usec = 0;
+ std::map<uint64_t, uint32_t>::iterator iterator = m_thread_id_to_used_usec_map.find(thread_id);
+ if (iterator != m_thread_id_to_used_usec_map.end())
+ {
+ prev_used_usec = m_thread_id_to_used_usec_map[thread_id];
+ }
+
+ uint32_t real_used_usec = curr_used_usec - prev_used_usec;
+ // A good first time record is one that runs for at least 0.25 sec
+ bool good_first_time = (prev_used_usec == 0) && (real_used_usec > 250000);
+ bool good_subsequent_time = (prev_used_usec > 0) &&
+ ((real_used_usec > 0) || (process->HasAssignedIndexIDToThread(thread_id)));
+
+ if (good_first_time || good_subsequent_time)
+ {
+ // We try to avoid doing too many index id reservation,
+ // resulting in fast increase of index ids.
+
+ final_output << name << ":";
+ int32_t index_id = process->AssignIndexIDToThread(thread_id);
+ final_output << index_id << ";";
+
+ final_output << usec_name << ":" << usec_value << ";";
+ }
+ else
+ {
+ // Skip past 'thread_used_name'.
+ std::string local_name, local_value;
+ profileDataExtractor.GetNameColonValue(local_name, local_value);
+ }
+
+ // Store current time as previous time so that they can be compared later.
+ new_thread_id_to_used_usec_map[thread_id] = curr_used_usec;
+ }
+ else
+ {
+ // Bail out and use old string.
+ final_output << name << ":" << value << ";";
+ }
+ }
+ else
+ {
+ final_output << name << ":" << value << ";";
+ }
+ }
+ final_output << end_delimiter;
+ m_thread_id_to_used_usec_map = new_thread_id_to_used_usec_map;
+
+ return final_output.str();
+}
+
StateType
GDBRemoteCommunicationClient::SendContinuePacketAndWaitForResponse
(
@@ -435,7 +531,7 @@ GDBRemoteCommunicationClient::SendContin
)
{
m_curr_tid = LLDB_INVALID_THREAD_ID;
- LogSP log (ProcessGDBRemoteLog::GetLogIfAllCategoriesSet (GDBR_LOG_PROCESS));
+ Log *log (ProcessGDBRemoteLog::GetLogIfAllCategoriesSet (GDBR_LOG_PROCESS));
if (log)
log->Printf ("GDBRemoteCommunicationClient::%s ()", __FUNCTION__);
@@ -448,11 +544,11 @@ GDBRemoteCommunicationClient::SendContin
// may change if we are interrupted and we continue after an async packet...
std::string continue_packet(payload, packet_length);
- bool got_stdout = false;
+ bool got_async_packet = false;
while (state == eStateRunning)
{
- if (!got_stdout)
+ if (!got_async_packet)
{
if (log)
log->Printf ("GDBRemoteCommunicationClient::%s () sending continue packet: %s", __FUNCTION__, continue_packet.c_str());
@@ -462,7 +558,7 @@ GDBRemoteCommunicationClient::SendContin
m_private_is_running.SetValue (true, eBroadcastAlways);
}
- got_stdout = false;
+ got_async_packet = false;
if (log)
log->Printf ("GDBRemoteCommunicationClient::%s () WaitForPacket(%s)", __FUNCTION__, continue_packet.c_str());
@@ -585,7 +681,7 @@ GDBRemoteCommunicationClient::SendContin
}
else if (m_async_packet_predicate.GetValue())
{
- LogSP packet_log (ProcessGDBRemoteLog::GetLogIfAllCategoriesSet (GDBR_LOG_PACKETS));
+ Log * packet_log (ProcessGDBRemoteLog::GetLogIfAllCategoriesSet (GDBR_LOG_PACKETS));
// We are supposed to send an asynchronous packet while
// we are running.
@@ -645,7 +741,7 @@ GDBRemoteCommunicationClient::SendContin
case 'O':
// STDOUT
{
- got_stdout = true;
+ got_async_packet = true;
std::string inferior_stdout;
inferior_stdout.reserve(response.GetBytesLeft () / 2);
char ch;
@@ -658,10 +754,30 @@ GDBRemoteCommunicationClient::SendContin
case 'A':
// Async miscellaneous reply. Right now, only profile data is coming through this channel.
{
- const std::string& profile_data = response.GetStringRef();
- const char *data_cstr = profile_data.c_str();
- data_cstr++; // Move beyond 'A'
- process->BroadcastAsyncProfileData (data_cstr, profile_data.size()-1);
+ got_async_packet = true;
+ std::string input = response.GetStringRef().substr(1); // '1' to move beyond 'A'
+ if (m_partial_profile_data.length() > 0)
+ {
+ m_partial_profile_data.append(input);
+ input = m_partial_profile_data;
+ m_partial_profile_data.clear();
+ }
+
+ size_t found, pos = 0, len = input.length();
+ while ((found = input.find(end_delimiter, pos)) != std::string::npos)
+ {
+ StringExtractorGDBRemote profileDataExtractor(input.substr(pos, found).c_str());
+ const std::string& profile_data = HarmonizeThreadIdsForProfileData(process, profileDataExtractor);
+ process->BroadcastAsyncProfileData (profile_data.c_str(), profile_data.length());
+
+ pos = found + end_delimiter_len;
+ }
+
+ if (pos < len)
+ {
+ // Last incomplete chunk.
+ m_partial_profile_data = input.substr(pos);
+ }
}
break;
@@ -725,7 +841,7 @@ GDBRemoteCommunicationClient::SendInterr
)
{
timed_out = false;
- LogSP log (ProcessGDBRemoteLog::GetLogIfAnyCategoryIsSet (GDBR_LOG_PROCESS | GDBR_LOG_PACKETS));
+ Log *log (ProcessGDBRemoteLog::GetLogIfAnyCategoryIsSet (GDBR_LOG_PROCESS | GDBR_LOG_PACKETS));
if (IsRunning())
{
@@ -2003,17 +2119,17 @@ GDBRemoteCommunicationClient::LaunchGDBs
}
bool
-GDBRemoteCommunicationClient::SetCurrentThread (int tid)
+GDBRemoteCommunicationClient::SetCurrentThread (uint64_t tid)
{
if (m_curr_tid == tid)
return true;
-
+
char packet[32];
int packet_len;
- if (tid <= 0)
- packet_len = ::snprintf (packet, sizeof(packet), "Hg%i", tid);
+ if (tid == UINT64_MAX)
+ packet_len = ::snprintf (packet, sizeof(packet), "Hg-1");
else
- packet_len = ::snprintf (packet, sizeof(packet), "Hg%x", tid);
+ packet_len = ::snprintf (packet, sizeof(packet), "Hg%" PRIx64, tid);
assert (packet_len + 1 < sizeof(packet));
StringExtractorGDBRemote response;
if (SendPacketAndWaitForResponse(packet, packet_len, response, false))
@@ -2028,18 +2144,18 @@ GDBRemoteCommunicationClient::SetCurrent
}
bool
-GDBRemoteCommunicationClient::SetCurrentThreadForRun (int tid)
+GDBRemoteCommunicationClient::SetCurrentThreadForRun (uint64_t tid)
{
if (m_curr_tid_run == tid)
return true;
-
+
char packet[32];
int packet_len;
- if (tid <= 0)
- packet_len = ::snprintf (packet, sizeof(packet), "Hc%i", tid);
+ if (tid == UINT64_MAX)
+ packet_len = ::snprintf (packet, sizeof(packet), "Hc-1");
else
- packet_len = ::snprintf (packet, sizeof(packet), "Hc%x", tid);
-
+ packet_len = ::snprintf (packet, sizeof(packet), "Hc%" PRIx64, tid);
+
assert (packet_len + 1 < sizeof(packet));
StringExtractorGDBRemote response;
if (SendPacketAndWaitForResponse(packet, packet_len, response, false))
@@ -2155,7 +2271,7 @@ GDBRemoteCommunicationClient::GetCurrent
{
do
{
- tid_t tid = response.GetHexMaxU32(false, LLDB_INVALID_THREAD_ID);
+ tid_t tid = response.GetHexMaxU64(false, LLDB_INVALID_THREAD_ID);
if (tid != LLDB_INVALID_THREAD_ID)
{
@@ -2171,7 +2287,7 @@ GDBRemoteCommunicationClient::GetCurrent
#if defined (LLDB_CONFIGURATION_DEBUG)
// assert(!"ProcessGDBRemote::UpdateThreadList() failed due to not getting the sequence mutex");
#else
- LogSP log (ProcessGDBRemoteLog::GetLogIfAnyCategoryIsSet (GDBR_LOG_PROCESS | GDBR_LOG_PACKETS));
+ Log *log (ProcessGDBRemoteLog::GetLogIfAnyCategoryIsSet (GDBR_LOG_PROCESS | GDBR_LOG_PACKETS));
if (log)
log->Printf("error: failed to get packet sequence mutex, not sending packet 'qfThreadInfo'");
#endif
Modified: lldb/branches/windows/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.h
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/windows/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.h?rev=179679&r1=179678&r2=179679&view=diff
==============================================================================
--- lldb/branches/windows/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.h (original)
+++ lldb/branches/windows/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.h Wed Apr 17 03:38:48 2013
@@ -332,10 +332,10 @@ public:
uint32_t recv_size);
bool
- SetCurrentThread (int tid);
+ SetCurrentThread (uint64_t tid);
bool
- SetCurrentThreadForRun (int tid);
+ SetCurrentThreadForRun (uint64_t tid);
lldb_private::LazyBool
SupportsAllocDeallocMemory () // const
@@ -354,6 +354,11 @@ public:
{
return m_interrupt_sent;
}
+
+ std::string
+ HarmonizeThreadIdsForProfileData (ProcessGDBRemote *process,
+ StringExtractorGDBRemote &inputStringExtractor);
+
protected:
bool
@@ -407,6 +412,8 @@ protected:
StringExtractorGDBRemote m_async_response;
int m_async_signal; // We were asked to deliver a signal to the inferior process.
bool m_interrupt_sent;
+ std::string m_partial_profile_data;
+ std::map<uint64_t, uint32_t> m_thread_id_to_used_usec_map;
lldb_private::ArchSpec m_host_arch;
lldb_private::ArchSpec m_process_arch;
Modified: lldb/branches/windows/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServer.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/windows/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServer.cpp?rev=179679&r1=179678&r2=179679&view=diff
==============================================================================
--- lldb/branches/windows/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServer.cpp (original)
+++ lldb/branches/windows/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServer.cpp Wed Apr 17 03:38:48 2013
@@ -60,7 +60,7 @@ GDBRemoteCommunicationServer::~GDBRemote
//{
// GDBRemoteCommunicationServer *server = (GDBRemoteCommunicationServer*) arg;
//
-// LogSP log;// (ProcessGDBRemoteLog::GetLogIfAllCategoriesSet (GDBR_LOG_PROCESS));
+// Log *log;// (ProcessGDBRemoteLog::GetLogIfAllCategoriesSet (GDBR_LOG_PROCESS));
// if (log)
// log->Printf ("ProcessGDBRemote::%s (arg = %p, pid = %i) thread starting...", __FUNCTION__, arg, process->GetID());
//
Modified: lldb/branches/windows/source/Plugins/Process/gdb-remote/GDBRemoteRegisterContext.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/windows/source/Plugins/Process/gdb-remote/GDBRemoteRegisterContext.cpp?rev=179679&r1=179678&r2=179679&view=diff
==============================================================================
--- lldb/branches/windows/source/Plugins/Process/gdb-remote/GDBRemoteRegisterContext.cpp (original)
+++ lldb/branches/windows/source/Plugins/Process/gdb-remote/GDBRemoteRegisterContext.cpp Wed Apr 17 03:38:48 2013
@@ -85,7 +85,7 @@ GDBRemoteRegisterContext::GetRegisterCou
}
const RegisterInfo *
-GDBRemoteRegisterContext::GetRegisterInfoAtIndex (uint32_t reg)
+GDBRemoteRegisterContext::GetRegisterInfoAtIndex (size_t reg)
{
return m_reg_info.GetRegisterInfoAtIndex (reg);
}
@@ -99,7 +99,7 @@ GDBRemoteRegisterContext::GetRegisterSet
const RegisterSet *
-GDBRemoteRegisterContext::GetRegisterSet (uint32_t reg_set)
+GDBRemoteRegisterContext::GetRegisterSet (size_t reg_set)
{
return m_reg_info.GetRegisterSet (reg_set);
}
@@ -134,13 +134,13 @@ GDBRemoteRegisterContext::PrivateSetRegi
bool success = bytes_copied == reg_byte_size;
if (success)
{
- m_reg_valid[reg] = true;
+ SetRegisterIsValid(reg, true);
}
else if (bytes_copied > 0)
{
// Only set register is valid to false if we copied some bytes, else
// leave it as it was.
- m_reg_valid[reg] = false;
+ SetRegisterIsValid(reg, false);
}
return success;
}
@@ -180,7 +180,7 @@ GDBRemoteRegisterContext::ReadRegisterBy
const uint32_t reg = reg_info->kinds[eRegisterKindLLDB];
- if (!m_reg_valid[reg])
+ if (!GetRegisterIsValid(reg))
{
Mutex::Locker locker;
if (gdb_comm.GetSequenceMutex (locker, "Didn't get sequence mutex for read register."))
@@ -207,51 +207,54 @@ GDBRemoteRegisterContext::ReadRegisterBy
SetAllRegisterValid (true);
}
}
- else if (!reg_info->value_regs)
- {
- // Get each register individually
- GetPrimordialRegister(reg_info, gdb_comm);
- }
- else
+ else if (reg_info->value_regs)
{
// Process this composite register request by delegating to the constituent
// primordial registers.
-
+
// Index of the primordial register.
- uint32_t prim_reg_idx;
bool success = true;
- for (uint32_t idx = 0;
- (prim_reg_idx = reg_info->value_regs[idx]) != LLDB_INVALID_REGNUM;
- ++idx)
+ for (uint32_t idx = 0; success; ++idx)
{
+ const uint32_t prim_reg = reg_info->value_regs[idx];
+ if (prim_reg == LLDB_INVALID_REGNUM)
+ break;
// We have a valid primordial regsiter as our constituent.
// Grab the corresponding register info.
- const RegisterInfo *prim_reg_info = GetRegisterInfoAtIndex(prim_reg_idx);
- if (!GetPrimordialRegister(prim_reg_info, gdb_comm))
- {
+ const RegisterInfo *prim_reg_info = GetRegisterInfoAtIndex(prim_reg);
+ if (prim_reg_info == NULL)
success = false;
- // Some failure occurred. Let's break out of the for loop.
- break;
+ else
+ {
+ // Read the containing register if it hasn't already been read
+ if (!GetRegisterIsValid(prim_reg))
+ success = GetPrimordialRegister(prim_reg_info, gdb_comm);
}
}
+
if (success)
{
// If we reach this point, all primordial register requests have succeeded.
// Validate this composite register.
- m_reg_valid[reg_info->kinds[eRegisterKindLLDB]] = true;
+ SetRegisterIsValid (reg_info, true);
}
}
+ else
+ {
+ // Get each register individually
+ GetPrimordialRegister(reg_info, gdb_comm);
+ }
}
}
else
{
- LogSP log (ProcessGDBRemoteLog::GetLogIfAnyCategoryIsSet (GDBR_LOG_THREAD | GDBR_LOG_PACKETS));
#if LLDB_CONFIGURATION_DEBUG
StreamString strm;
gdb_comm.DumpHistory(strm);
Host::SetCrashDescription (strm.GetData());
assert (!"Didn't get sequence mutex for read register.");
#else
+ Log *log (ProcessGDBRemoteLog::GetLogIfAnyCategoryIsSet (GDBR_LOG_THREAD | GDBR_LOG_PACKETS));
if (log)
{
if (log->GetVerbose())
@@ -269,7 +272,7 @@ GDBRemoteRegisterContext::ReadRegisterBy
}
// Make sure we got a valid register value after reading it
- if (!m_reg_valid[reg])
+ if (!GetRegisterIsValid(reg))
return false;
}
@@ -314,7 +317,7 @@ GDBRemoteRegisterContext::SetPrimordialR
packet.Printf (";thread:%4.4" PRIx64 ";", m_thread.GetID());
// Invalidate just this register
- m_reg_valid[reg] = false;
+ SetRegisterIsValid(reg, false);
if (gdb_comm.SendPacketAndWaitForResponse(packet.GetString().c_str(),
packet.GetString().size(),
response,
@@ -387,6 +390,7 @@ GDBRemoteRegisterContext::WriteRegisterB
{
StreamString packet;
StringExtractorGDBRemote response;
+
if (m_read_all_at_once)
{
// Set all registers in one packet
@@ -414,59 +418,57 @@ GDBRemoteRegisterContext::WriteRegisterB
}
}
}
- else if (!reg_info->value_regs)
- {
- // Set each register individually
- return SetPrimordialRegister(reg_info, gdb_comm);
- }
else
{
- // Process this composite register request by delegating to the constituent
- // primordial registers.
-
- // Invalidate this composite register first.
- m_reg_valid[reg_info->kinds[eRegisterKindLLDB]] = false;
-
- // Index of the primordial register.
- uint32_t prim_reg_idx;
- // For loop index.
- uint32_t idx;
+ bool success = true;
- // Invalidate the invalidate_regs, if present.
- if (reg_info->invalidate_regs)
+ if (reg_info->value_regs)
{
- for (idx = 0;
- (prim_reg_idx = reg_info->invalidate_regs[idx]) != LLDB_INVALID_REGNUM;
- ++idx)
+ // This register is part of another register. In this case we read the actual
+ // register data for any "value_regs", and once all that data is read, we will
+ // have enough data in our register context bytes for the value of this register
+
+ // Invalidate this composite register first.
+
+ for (uint32_t idx = 0; success; ++idx)
{
- // Grab the invalidate register info.
- const RegisterInfo *prim_reg_info = GetRegisterInfoAtIndex(prim_reg_idx);
- m_reg_valid[prim_reg_info->kinds[eRegisterKindLLDB]] = false;
+ const uint32_t reg = reg_info->value_regs[idx];
+ if (reg == LLDB_INVALID_REGNUM)
+ break;
+ // We have a valid primordial regsiter as our constituent.
+ // Grab the corresponding register info.
+ const RegisterInfo *value_reg_info = GetRegisterInfoAtIndex(reg);
+ if (value_reg_info == NULL)
+ success = false;
+ else
+ success = SetPrimordialRegister(value_reg_info, gdb_comm);
}
}
+ else
+ {
+ // This is an actual register, write it
+ success = SetPrimordialRegister(reg_info, gdb_comm);
+ }
- bool success = true;
- for (idx = 0;
- (prim_reg_idx = reg_info->value_regs[idx]) != LLDB_INVALID_REGNUM;
- ++idx)
+ // Check if writing this register will invalidate any other register values?
+ // If so, invalidate them
+ if (reg_info->invalidate_regs)
{
- // We have a valid primordial regsiter as our constituent.
- // Grab the corresponding register info.
- const RegisterInfo *prim_reg_info = GetRegisterInfoAtIndex(prim_reg_idx);
- if (!SetPrimordialRegister(prim_reg_info, gdb_comm))
+ for (uint32_t idx = 0, reg = reg_info->invalidate_regs[0];
+ reg != LLDB_INVALID_REGNUM;
+ reg = reg_info->invalidate_regs[++idx])
{
- success = false;
- // Some failure occurred. Let's break out of the for loop.
- break;
+ SetRegisterIsValid(reg, false);
}
}
+
return success;
}
}
}
else
{
- LogSP log (ProcessGDBRemoteLog::GetLogIfAnyCategoryIsSet (GDBR_LOG_THREAD | GDBR_LOG_PACKETS));
+ Log *log (ProcessGDBRemoteLog::GetLogIfAnyCategoryIsSet (GDBR_LOG_THREAD | GDBR_LOG_PACKETS));
if (log)
{
if (log->GetVerbose())
@@ -538,7 +540,7 @@ GDBRemoteRegisterContext::ReadAllRegiste
}
else
{
- LogSP log (ProcessGDBRemoteLog::GetLogIfAnyCategoryIsSet (GDBR_LOG_THREAD | GDBR_LOG_PACKETS));
+ Log *log (ProcessGDBRemoteLog::GetLogIfAnyCategoryIsSet (GDBR_LOG_THREAD | GDBR_LOG_PACKETS));
if (log)
{
if (log->GetVerbose())
@@ -633,7 +635,7 @@ GDBRemoteRegisterContext::WriteAllRegist
const char *restore_src = (const char *)restore_data.PeekData(reg_byte_offset, reg_byte_size);
if (restore_src)
{
- if (m_reg_valid[reg])
+ if (GetRegisterIsValid(reg))
{
const char *current_src = (const char *)m_reg_data.PeekData(reg_byte_offset, reg_byte_size);
if (current_src)
@@ -652,7 +654,7 @@ GDBRemoteRegisterContext::WriteAllRegist
if (thread_suffix_supported)
packet.Printf (";thread:%4.4" PRIx64 ";", m_thread.GetID());
- m_reg_valid[reg] = false;
+ SetRegisterIsValid(reg, false);
if (gdb_comm.SendPacketAndWaitForResponse(packet.GetString().c_str(),
packet.GetString().size(),
response,
@@ -671,7 +673,7 @@ GDBRemoteRegisterContext::WriteAllRegist
}
else
{
- LogSP log (ProcessGDBRemoteLog::GetLogIfAnyCategoryIsSet (GDBR_LOG_THREAD | GDBR_LOG_PACKETS));
+ Log *log (ProcessGDBRemoteLog::GetLogIfAnyCategoryIsSet (GDBR_LOG_THREAD | GDBR_LOG_PACKETS));
if (log)
{
if (log->GetVerbose())
@@ -855,7 +857,7 @@ GDBRemoteDynamicRegisterInfo::HardcodeAR
static ConstString gpr_reg_set ("General Purpose Registers");
static ConstString sfp_reg_set ("Software Floating Point Registers");
static ConstString vfp_reg_set ("Floating Point Registers");
- uint32_t i;
+ size_t i;
if (from_scratch)
{
// Calculate the offsets of the registers
@@ -903,121 +905,67 @@ GDBRemoteDynamicRegisterInfo::HardcodeAR
else
{
// Add composite registers to our primordial registers, then.
- const uint32_t num_composites = llvm::array_lengthof(g_composites);
- const uint32_t num_primordials = GetNumRegisters();
- RegisterInfo *g_comp_register_infos = g_register_infos + (num_registers - num_composites);
- for (i=0; i<num_composites; ++i)
+ const size_t num_composites = llvm::array_lengthof(g_composites);
+ const size_t num_dynamic_regs = GetNumRegisters();
+ const size_t num_common_regs = num_registers - num_composites;
+ RegisterInfo *g_comp_register_infos = g_register_infos + num_common_regs;
+
+ // First we need to validate that all registers that we already have match the non composite regs.
+ // If so, then we can add the registers, else we need to bail
+ bool match = true;
+ if (num_dynamic_regs == num_common_regs)
{
- ConstString name;
- ConstString alt_name;
- const uint32_t first_primordial_reg = g_comp_register_infos[i].value_regs[0];
- const char *reg_name = g_register_infos[first_primordial_reg].name;
- if (reg_name && reg_name[0])
- {
- for (uint32_t j = 0; j < num_primordials; ++j)
- {
- const RegisterInfo *reg_info = GetRegisterInfoAtIndex(j);
- // Find a matching primordial register info entry.
- if (reg_info && reg_info->name && ::strcasecmp(reg_info->name, reg_name) == 0)
- {
- // The name matches the existing primordial entry.
- // Find and assign the offset, and then add this composite register entry.
- g_comp_register_infos[i].byte_offset = reg_info->byte_offset;
- name.SetCString(g_comp_register_infos[i].name);
- AddRegister(g_comp_register_infos[i], name, alt_name, vfp_reg_set);
+ for (i=0; match && i<num_dynamic_regs; ++i)
+ {
+ // Make sure all register names match
+ if (m_regs[i].name && g_register_infos[i].name)
+ {
+ if (strcmp(m_regs[i].name, g_register_infos[i].name))
+ {
+ match = false;
+ break;
}
}
+
+ // Make sure all register byte sizes match
+ if (m_regs[i].byte_size != g_register_infos[i].byte_size)
+ {
+ match = false;
+ break;
+ }
}
}
- }
-}
-
-void
-GDBRemoteDynamicRegisterInfo::Addx86_64ConvenienceRegisters()
-{
- // For eax, ebx, ecx, edx, esi, edi, ebp, esp register mapping.
- static const char* g_mapped_names[] = {
- "rax", "rbx", "rcx", "rdx", "rdi", "rsi", "rbp", "rsp",
- "rax", "rbx", "rcx", "rdx", "rdi", "rsi", "rbp", "rsp",
- "rax", "rbx", "rcx", "rdx",
- "rax", "rbx", "rcx", "rdx", "rdi", "rsi", "rbp", "rsp"
- };
-
- // These value regs are to be populated with the corresponding primordial register index.
- // For example,
- static uint32_t g_eax_regs[] = { 0, LLDB_INVALID_REGNUM }; // 0 is to be replaced with rax's index.
- static uint32_t g_ebx_regs[] = { 0, LLDB_INVALID_REGNUM };
- static uint32_t g_ecx_regs[] = { 0, LLDB_INVALID_REGNUM };
- static uint32_t g_edx_regs[] = { 0, LLDB_INVALID_REGNUM };
- static uint32_t g_edi_regs[] = { 0, LLDB_INVALID_REGNUM };
- static uint32_t g_esi_regs[] = { 0, LLDB_INVALID_REGNUM };
- static uint32_t g_ebp_regs[] = { 0, LLDB_INVALID_REGNUM };
- static uint32_t g_esp_regs[] = { 0, LLDB_INVALID_REGNUM };
-
- static RegisterInfo g_conv_register_infos[] =
- {
-// NAME ALT SZ OFF ENCODING FORMAT COMPILER DWARF GENERIC GDB LLDB NATIVE VALUE REGS INVALIDATE REGS
-// ====== ======= == === ============= ============ ===================== ===================== ============================ ==================== ====================== ========== ===============
- { "eax" , NULL, 4, 0, eEncodingUint , eFormatHex , { LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM }, g_eax_regs, NULL},
- { "ebx" , NULL, 4, 0, eEncodingUint , eFormatHex , { LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM }, g_ebx_regs, NULL},
- { "ecx" , NULL, 4, 0, eEncodingUint , eFormatHex , { LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM }, g_ecx_regs, NULL},
- { "edx" , NULL, 4, 0, eEncodingUint , eFormatHex , { LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM }, g_edx_regs, NULL},
- { "edi" , NULL, 4, 0, eEncodingUint , eFormatHex , { LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM }, g_edi_regs, NULL},
- { "esi" , NULL, 4, 0, eEncodingUint , eFormatHex , { LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM }, g_esi_regs, NULL},
- { "ebp" , NULL, 4, 0, eEncodingUint , eFormatHex , { LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM }, g_ebp_regs, NULL},
- { "esp" , NULL, 4, 0, eEncodingUint , eFormatHex , { LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM }, g_esp_regs, NULL},
- { "ax" , NULL, 2, 0, eEncodingUint , eFormatHex , { LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM }, g_eax_regs, NULL},
- { "bx" , NULL, 2, 0, eEncodingUint , eFormatHex , { LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM }, g_ebx_regs, NULL},
- { "cx" , NULL, 2, 0, eEncodingUint , eFormatHex , { LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM }, g_ecx_regs, NULL},
- { "dx" , NULL, 2, 0, eEncodingUint , eFormatHex , { LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM }, g_edx_regs, NULL},
- { "di" , NULL, 2, 0, eEncodingUint , eFormatHex , { LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM }, g_edi_regs, NULL},
- { "si" , NULL, 2, 0, eEncodingUint , eFormatHex , { LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM }, g_esi_regs, NULL},
- { "bp" , NULL, 2, 0, eEncodingUint , eFormatHex , { LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM }, g_ebp_regs, NULL},
- { "sp" , NULL, 2, 0, eEncodingUint , eFormatHex , { LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM }, g_esp_regs, NULL},
- { "ah" , NULL, 1, 1, eEncodingUint , eFormatHex , { LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM }, g_eax_regs, NULL},
- { "bh" , NULL, 1, 1, eEncodingUint , eFormatHex , { LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM }, g_ebx_regs, NULL},
- { "ch" , NULL, 1, 1, eEncodingUint , eFormatHex , { LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM }, g_ecx_regs, NULL},
- { "dh" , NULL, 1, 1, eEncodingUint , eFormatHex , { LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM }, g_edx_regs, NULL},
- { "al" , NULL, 1, 0, eEncodingUint , eFormatHex , { LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM }, g_eax_regs, NULL},
- { "bl" , NULL, 1, 0, eEncodingUint , eFormatHex , { LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM }, g_ebx_regs, NULL},
- { "cl" , NULL, 1, 0, eEncodingUint , eFormatHex , { LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM }, g_ecx_regs, NULL},
- { "dl" , NULL, 1, 0, eEncodingUint , eFormatHex , { LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM }, g_edx_regs, NULL},
- { "dil" , NULL, 1, 0, eEncodingUint , eFormatHex , { LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM }, g_edi_regs, NULL},
- { "sil" , NULL, 1, 0, eEncodingUint , eFormatHex , { LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM }, g_esi_regs, NULL},
- { "bpl" , NULL, 1, 0, eEncodingUint , eFormatHex , { LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM }, g_ebp_regs, NULL},
- { "spl" , NULL, 1, 0, eEncodingUint , eFormatHex , { LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM , LLDB_INVALID_REGNUM }, g_esp_regs, NULL}
- };
-
- static const uint32_t num_conv_regs = llvm::array_lengthof(g_mapped_names);
- static ConstString gpr_reg_set ("General Purpose Registers");
-
- // Add convenience registers to our primordial registers.
- const uint32_t num_primordials = GetNumRegisters();
- uint32_t reg_kind = num_primordials;
- for (uint32_t i=0; i<num_conv_regs; ++i)
- {
- ConstString name;
- ConstString alt_name;
- const char *prim_reg_name = g_mapped_names[i];
- if (prim_reg_name && prim_reg_name[0])
- {
- for (uint32_t j = 0; j < num_primordials; ++j)
- {
- const RegisterInfo *reg_info = GetRegisterInfoAtIndex(j);
- // Find a matching primordial register info entry.
- if (reg_info && reg_info->name && ::strcasecmp(reg_info->name, prim_reg_name) == 0)
- {
- // The name matches the existing primordial entry.
- // Find and assign the offset, and then add this composite register entry.
- g_conv_register_infos[i].byte_offset = reg_info->byte_offset + g_conv_register_infos[i].byte_offset;
- // Update the value_regs and the kinds fields in order to delegate to the primordial register.
- g_conv_register_infos[i].value_regs[0] = j;
- g_conv_register_infos[i].kinds[eRegisterKindLLDB] = ++reg_kind;
- name.SetCString(g_conv_register_infos[i].name);
- AddRegister(g_conv_register_infos[i], name, alt_name, gpr_reg_set);
+ else
+ {
+ // Wrong number of registers.
+ match = false;
+ }
+ // If "match" is true, then we can add extra registers.
+ if (match)
+ {
+ for (i=0; i<num_composites; ++i)
+ {
+ ConstString name;
+ ConstString alt_name;
+ const uint32_t first_primordial_reg = g_comp_register_infos[i].value_regs[0];
+ const char *reg_name = g_register_infos[first_primordial_reg].name;
+ if (reg_name && reg_name[0])
+ {
+ for (uint32_t j = 0; j < num_dynamic_regs; ++j)
+ {
+ const RegisterInfo *reg_info = GetRegisterInfoAtIndex(j);
+ // Find a matching primordial register info entry.
+ if (reg_info && reg_info->name && ::strcasecmp(reg_info->name, reg_name) == 0)
+ {
+ // The name matches the existing primordial entry.
+ // Find and assign the offset, and then add this composite register entry.
+ g_comp_register_infos[i].byte_offset = reg_info->byte_offset;
+ name.SetCString(g_comp_register_infos[i].name);
+ AddRegister(g_comp_register_infos[i], name, alt_name, vfp_reg_set);
+ }
+ }
}
}
}
}
}
-
Modified: lldb/branches/windows/source/Plugins/Process/gdb-remote/GDBRemoteRegisterContext.h
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/windows/source/Plugins/Process/gdb-remote/GDBRemoteRegisterContext.h?rev=179679&r1=179678&r2=179679&view=diff
==============================================================================
--- lldb/branches/windows/source/Plugins/Process/gdb-remote/GDBRemoteRegisterContext.h (original)
+++ lldb/branches/windows/source/Plugins/Process/gdb-remote/GDBRemoteRegisterContext.h Wed Apr 17 03:38:48 2013
@@ -46,19 +46,34 @@ public:
}
void
- AddRegister (lldb_private::RegisterInfo ®_info,
+ AddRegister (lldb_private::RegisterInfo reg_info,
lldb_private::ConstString ®_name,
lldb_private::ConstString ®_alt_name,
lldb_private::ConstString &set_name)
{
- const uint32_t reg_num = m_regs.size();
+ const uint32_t reg_num = (uint32_t)m_regs.size();
m_reg_names.push_back (reg_name);
m_reg_alt_names.push_back (reg_alt_name);
reg_info.name = reg_name.AsCString();
assert (reg_info.name);
reg_info.alt_name = reg_alt_name.AsCString(NULL);
+ uint32_t i;
+ if (reg_info.value_regs)
+ {
+ for (i=0; reg_info.value_regs[i] != LLDB_INVALID_REGNUM; ++i)
+ m_value_regs_map[reg_num].push_back(reg_info.value_regs[i]);
+ m_value_regs_map[reg_num].push_back(LLDB_INVALID_REGNUM);
+ reg_info.value_regs = m_value_regs_map[reg_num].data();
+ }
+ if (reg_info.invalidate_regs)
+ {
+ for (i=0; reg_info.invalidate_regs[i] != LLDB_INVALID_REGNUM; ++i)
+ m_invalidate_regs_map[reg_num].push_back(reg_info.invalidate_regs[i]);
+ m_invalidate_regs_map[reg_num].push_back(LLDB_INVALID_REGNUM);
+ reg_info.invalidate_regs = m_invalidate_regs_map[reg_num].data();
+ }
m_regs.push_back (reg_info);
- uint32_t set = GetRegisterSetIndexByName (set_name, true);
+ uint32_t set = GetRegisterSetIndexByName (set_name);
assert (set < m_sets.size());
assert (set < m_set_reg_nums.size());
assert (set < m_set_names.size());
@@ -114,20 +129,20 @@ public:
}
uint32_t
- GetRegisterSetIndexByName (lldb_private::ConstString &set_name, bool can_create)
+ GetRegisterSetIndexByName (lldb_private::ConstString &set_name)
{
name_collection::iterator pos, end = m_set_names.end();
for (pos = m_set_names.begin(); pos != end; ++pos)
{
if (*pos == set_name)
- return std::distance (m_set_names.begin(), pos);
+ return static_cast<uint32_t>(std::distance (m_set_names.begin(), pos));
}
m_set_names.push_back(set_name);
m_set_reg_nums.resize(m_set_reg_nums.size()+1);
lldb_private::RegisterSet new_set = { set_name.AsCString(), NULL, 0, NULL };
m_sets.push_back (new_set);
- return m_sets.size() - 1;
+ return static_cast<uint32_t>(m_sets.size() - 1);
}
uint32_t
@@ -137,7 +152,7 @@ public:
for (pos = m_regs.begin(); pos != end; ++pos)
{
if (pos->kinds[kind] == num)
- return std::distance (m_regs.begin(), pos);
+ return static_cast<uint32_t>(std::distance (m_regs.begin(), pos));
}
return LLDB_INVALID_REGNUM;
@@ -156,9 +171,6 @@ public:
void
HardcodeARMRegisters(bool from_scratch);
- void
- Addx86_64ConvenienceRegisters();
-
protected:
//------------------------------------------------------------------
// Classes that inherit from GDBRemoteRegisterContext can see and modify these
@@ -168,6 +180,7 @@ protected:
typedef std::vector <uint32_t> reg_num_collection;
typedef std::vector <reg_num_collection> set_reg_num_collection;
typedef std::vector <lldb_private::ConstString> name_collection;
+ typedef std::map<uint32_t, reg_num_collection> reg_to_regs_map;
reg_collection m_regs;
set_collection m_sets;
@@ -175,6 +188,8 @@ protected:
name_collection m_reg_names;
name_collection m_reg_alt_names;
name_collection m_set_names;
+ reg_to_regs_map m_value_regs_map;
+ reg_to_regs_map m_invalidate_regs_map;
size_t m_reg_data_byte_size; // The number of bytes required to store all registers
};
@@ -202,13 +217,13 @@ public:
GetRegisterCount ();
virtual const lldb_private::RegisterInfo *
- GetRegisterInfoAtIndex (uint32_t reg);
+ GetRegisterInfoAtIndex (size_t reg);
virtual size_t
GetRegisterSetCount ();
virtual const lldb_private::RegisterSet *
- GetRegisterSet (uint32_t reg_set);
+ GetRegisterSet (size_t reg_set);
virtual bool
ReadRegister (const lldb_private::RegisterInfo *reg_info, lldb_private::RegisterValue &value);
@@ -243,6 +258,34 @@ protected:
void
SetAllRegisterValid (bool b);
+ bool
+ GetRegisterIsValid (uint32_t reg) const
+ {
+#if defined (LLDB_CONFIGURATION_DEBUG)
+ assert (reg < m_reg_valid.size());
+#endif
+ if (reg < m_reg_valid.size())
+ return m_reg_valid[reg];
+ return false;
+ }
+
+ void
+ SetRegisterIsValid (const lldb_private::RegisterInfo *reg_info, bool valid)
+ {
+ if (reg_info)
+ return SetRegisterIsValid (reg_info->kinds[lldb::eRegisterKindLLDB], valid);
+ }
+
+ void
+ SetRegisterIsValid (uint32_t reg, bool valid)
+ {
+#if defined (LLDB_CONFIGURATION_DEBUG)
+ assert (reg < m_reg_valid.size());
+#endif
+ if (reg < m_reg_valid.size())
+ m_reg_valid[reg] = valid;
+ }
+
void
SyncThreadState(lldb_private::Process *process); // Assumes the sequence mutex has already been acquired.
Modified: lldb/branches/windows/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/windows/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp?rev=179679&r1=179678&r2=179679&view=diff
==============================================================================
--- lldb/branches/windows/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp (original)
+++ lldb/branches/windows/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp Wed Apr 17 03:38:48 2013
@@ -72,7 +72,6 @@
#include "ProcessGDBRemoteLog.h"
#include "ThreadGDBRemote.h"
-#include "Plugins/DynamicLoader/Darwin-Kernel/DynamicLoaderDarwinKernel.h"
namespace lldb
{
@@ -217,10 +216,9 @@ ProcessGDBRemote::ProcessGDBRemote(Targe
m_waiting_for_attach (false),
m_destroy_tried_resuming (false),
m_dyld_plugin_name(),
- m_kernel_load_addr (LLDB_INVALID_ADDRESS),
m_command_sp ()
{
- m_async_broadcaster.SetEventName (eBroadcastBitAsyncThreadShouldExit, "async thread should exit");
+ m_async_broadcaster.SetEventName (eBroadcastBitAsyncThreadShouldExit, "async thread should exit");
m_async_broadcaster.SetEventName (eBroadcastBitAsyncContinue, "async thread continue");
m_async_broadcaster.SetEventName (eBroadcastBitAsyncThreadDidExit, "async thread did exit");
}
@@ -293,6 +291,8 @@ ProcessGDBRemote::BuildDynamicRegisterIn
ConstString reg_name;
ConstString alt_name;
ConstString set_name;
+ std::vector<uint32_t> value_regs;
+ std::vector<uint32_t> invalidate_regs;
RegisterInfo reg_info = { NULL, // Name
NULL, // Alt name
0, // byte size
@@ -384,11 +384,52 @@ ProcessGDBRemote::BuildDynamicRegisterIn
{
reg_info.kinds[eRegisterKindGeneric] = Args::StringToGenericRegister (value.c_str());
}
+ else if (name.compare("container-regs") == 0)
+ {
+ std::pair<llvm::StringRef, llvm::StringRef> value_pair;
+ value_pair.second = value;
+ do
+ {
+ value_pair = value_pair.second.split(',');
+ if (!value_pair.first.empty())
+ {
+ uint32_t reg = Args::StringToUInt32 (value_pair.first.str().c_str(), LLDB_INVALID_REGNUM, 16);
+ if (reg != LLDB_INVALID_REGNUM)
+ value_regs.push_back (reg);
+ }
+ } while (!value_pair.second.empty());
+ }
+ else if (name.compare("invalidate-regs") == 0)
+ {
+ std::pair<llvm::StringRef, llvm::StringRef> value_pair;
+ value_pair.second = value;
+ do
+ {
+ value_pair = value_pair.second.split(',');
+ if (!value_pair.first.empty())
+ {
+ uint32_t reg = Args::StringToUInt32 (value_pair.first.str().c_str(), LLDB_INVALID_REGNUM, 16);
+ if (reg != LLDB_INVALID_REGNUM)
+ invalidate_regs.push_back (reg);
+ }
+ } while (!value_pair.second.empty());
+ }
}
reg_info.byte_offset = reg_offset;
assert (reg_info.byte_size != 0);
reg_offset += reg_info.byte_size;
+ if (!value_regs.empty())
+ {
+ value_regs.push_back(LLDB_INVALID_REGNUM);
+ reg_info.value_regs = value_regs.data();
+ }
+ if (!invalidate_regs.empty())
+ {
+ invalidate_regs.push_back(LLDB_INVALID_REGNUM);
+ reg_info.invalidate_regs = invalidate_regs.data();
+ }
+
m_register_info.AddRegister(reg_info, reg_name, alt_name, set_name);
}
}
@@ -428,11 +469,6 @@ ProcessGDBRemote::BuildDynamicRegisterIn
m_register_info.HardcodeARMRegisters(from_scratch);
}
- // Add some convenience registers (eax, ebx, ecx, edx, esi, edi, ebp, esp) to x86_64.
- if ((target_arch.IsValid() && target_arch.GetMachine() == llvm::Triple::x86_64)
- || (remote_arch.IsValid() && remote_arch.GetMachine() == llvm::Triple::x86_64))
- m_register_info.Addx86_64ConvenienceRegisters();
-
// At this point, we can finalize our register info.
m_register_info.Finalize ();
}
@@ -469,8 +505,6 @@ ProcessGDBRemote::DoConnectRemote (Strea
return error;
StartAsyncThread ();
- CheckForKernel (strm);
-
lldb::pid_t pid = m_gdb_comm.GetCurrentProcessID ();
if (pid == LLDB_INVALID_PROCESS_ID)
{
@@ -512,110 +546,6 @@ ProcessGDBRemote::DoConnectRemote (Strea
return error;
}
-// When we are establishing a connection to a remote system and we have no executable specified,
-// or the executable is a kernel, we may be looking at a KASLR situation (where the kernel has been
-// slid in memory.)
-//
-// This function tries to locate the kernel in memory if this is possibly a kernel debug session.
-//
-// If a kernel is found, return the address of the kernel in GetImageInfoAddress() -- the
-// DynamicLoaderDarwinKernel plugin uses this address as the kernel load address and will load the
-// binary, if needed, along with all the kexts.
-
-void
-ProcessGDBRemote::CheckForKernel (Stream *strm)
-{
- // early return if this isn't an "unknown" system (kernel debugging doesn't have a system type)
- const ArchSpec &gdb_remote_arch = m_gdb_comm.GetHostArchitecture();
- if (!gdb_remote_arch.IsValid() || gdb_remote_arch.GetTriple().getVendor() != llvm::Triple::UnknownVendor)
- return;
-
- Module *exe_module = GetTarget().GetExecutableModulePointer();
- ObjectFile *exe_objfile = NULL;
- if (exe_module)
- exe_objfile = exe_module->GetObjectFile();
-
- // early return if we have an executable and it is not a kernel--this is very unlikely to be a kernel debug session.
- if (exe_objfile
- && (exe_objfile->GetType() != ObjectFile::eTypeExecutable
- || exe_objfile->GetStrata() != ObjectFile::eStrataKernel))
- return;
-
- // See if the kernel is in memory at the File address (slide == 0) -- no work needed, if so.
- if (exe_objfile && exe_objfile->GetHeaderAddress().IsValid())
- {
- ModuleSP memory_module_sp;
- memory_module_sp = ReadModuleFromMemory (exe_module->GetFileSpec(), exe_objfile->GetHeaderAddress().GetFileAddress(), false, false);
- if (memory_module_sp.get()
- && memory_module_sp->GetUUID().IsValid()
- && memory_module_sp->GetUUID() == exe_module->GetUUID())
- {
- m_kernel_load_addr = exe_objfile->GetHeaderAddress().GetFileAddress();
- m_dyld_plugin_name = DynamicLoaderDarwinKernel::GetPluginNameStatic();
- SetCanJIT(false);
- return;
- }
- }
-
- // See if the kernel's load address is stored in the kernel's low globals page; this is
- // done when a debug boot-arg has been set.
-
- Error error;
- uint8_t buf[24];
- ModuleSP memory_module_sp;
- addr_t kernel_addr = LLDB_INVALID_ADDRESS;
-
- // First try the 32-bit
- if (memory_module_sp.get() == NULL)
- {
- DataExtractor data4 (buf, sizeof(buf), gdb_remote_arch.GetByteOrder(), 4);
- if (DoReadMemory (0xffff0110, buf, 4, error) == 4)
- {
- uint32_t offset = 0;
- kernel_addr = data4.GetU32(&offset);
- memory_module_sp = ReadModuleFromMemory (FileSpec("mach_kernel", false), kernel_addr, false, false);
- if (!memory_module_sp.get()
- || !memory_module_sp->GetUUID().IsValid()
- || memory_module_sp->GetObjectFile() == NULL
- || memory_module_sp->GetObjectFile()->GetType() != ObjectFile::eTypeExecutable
- || memory_module_sp->GetObjectFile()->GetStrata() != ObjectFile::eStrataKernel)
- {
- memory_module_sp.reset();
- }
- }
- }
-
- // Now try the 64-bit location
- if (memory_module_sp.get() == NULL)
- {
- DataExtractor data8 (buf, sizeof(buf), gdb_remote_arch.GetByteOrder(), 8);
- if (DoReadMemory (0xffffff8000002010ULL, buf, 8, error) == 8)
- {
- uint32_t offset = 0;
- kernel_addr = data8.GetU64(&offset);
- memory_module_sp = ReadModuleFromMemory (FileSpec("mach_kernel", false), kernel_addr, false, false);
- if (!memory_module_sp.get()
- || !memory_module_sp->GetUUID().IsValid()
- || memory_module_sp->GetObjectFile() == NULL
- || memory_module_sp->GetObjectFile()->GetType() != ObjectFile::eTypeExecutable
- || memory_module_sp->GetObjectFile()->GetStrata() != ObjectFile::eStrataKernel)
- {
- memory_module_sp.reset();
- }
- }
- }
-
- if (memory_module_sp.get()
- && memory_module_sp->GetArchitecture().IsValid()
- && memory_module_sp->GetArchitecture().GetTriple().getVendor() == llvm::Triple::Apple)
- {
- m_kernel_load_addr = kernel_addr;
- m_dyld_plugin_name = DynamicLoaderDarwinKernel::GetPluginNameStatic();
- SetCanJIT(false);
- return;
- }
-}
-
Error
ProcessGDBRemote::WillLaunchOrAttach ()
{
@@ -661,7 +591,7 @@ ProcessGDBRemote::DoLaunch (Module *exe_
// ::LogSetBitMask (GDBR_LOG_DEFAULT);
// ::LogSetOptions (LLDB_LOG_OPTION_THREADSAFE | LLDB_LOG_OPTION_PREPEND_TIMESTAMP | LLDB_LOG_OPTION_PREPEND_PROC_AND_THREAD);
// ::LogSetLogFile ("/dev/stdout");
- LogSP log (ProcessGDBRemoteLog::GetLogIfAllCategoriesSet (GDBR_LOG_PROCESS));
+ Log *log (ProcessGDBRemoteLog::GetLogIfAllCategoriesSet (GDBR_LOG_PROCESS));
ObjectFile * object_file = exe_module->GetObjectFile();
if (object_file)
@@ -881,7 +811,7 @@ ProcessGDBRemote::ConnectToDebugserver (
void
ProcessGDBRemote::DidLaunchOrAttach ()
{
- LogSP log (ProcessGDBRemoteLog::GetLogIfAllCategoriesSet (GDBR_LOG_PROCESS));
+ Log *log (ProcessGDBRemoteLog::GetLogIfAllCategoriesSet (GDBR_LOG_PROCESS));
if (log)
log->Printf ("ProcessGDBRemote::DidLaunch()");
if (GetID() != LLDB_INVALID_PROCESS_ID)
@@ -1119,7 +1049,7 @@ Error
ProcessGDBRemote::DoResume ()
{
Error error;
- LogSP log (ProcessGDBRemoteLog::GetLogIfAllCategoriesSet (GDBR_LOG_PROCESS));
+ Log *log (ProcessGDBRemoteLog::GetLogIfAllCategoriesSet (GDBR_LOG_PROCESS));
if (log)
log->Printf ("ProcessGDBRemote::Resume()");
@@ -1376,7 +1306,7 @@ bool
ProcessGDBRemote::UpdateThreadList (ThreadList &old_thread_list, ThreadList &new_thread_list)
{
// locker will keep a mutex locked until it goes out of scope
- LogSP log (ProcessGDBRemoteLog::GetLogIfAllCategoriesSet (GDBR_LOG_THREAD));
+ Log *log (ProcessGDBRemoteLog::GetLogIfAllCategoriesSet (GDBR_LOG_THREAD));
if (log && log->GetMask().Test(GDBR_LOG_VERBOSE))
log->Printf ("ProcessGDBRemote::%s (pid = %" PRIu64 ")", __FUNCTION__, GetID());
@@ -1390,18 +1320,32 @@ ProcessGDBRemote::UpdateThreadList (Thre
num_thread_ids = m_thread_ids.size();
}
+ ThreadList old_thread_list_copy(old_thread_list);
if (num_thread_ids > 0)
{
for (size_t i=0; i<num_thread_ids; ++i)
{
tid_t tid = m_thread_ids[i];
- ThreadSP thread_sp (old_thread_list.FindThreadByID (tid, false));
+ ThreadSP thread_sp (old_thread_list_copy.RemoveThreadByID (tid, false));
if (!thread_sp)
thread_sp.reset (new ThreadGDBRemote (*this, tid));
new_thread_list.AddThread(thread_sp);
}
}
-
+
+ // Whatever that is left in old_thread_list_copy are not
+ // present in new_thread_list. Remove non-existent threads from internal id table.
+ size_t old_num_thread_ids = old_thread_list_copy.GetSize(false);
+ for (size_t i=0; i<old_num_thread_ids; i++)
+ {
+ ThreadSP old_thread_sp(old_thread_list_copy.GetThreadAtIndex (i, false));
+ if (old_thread_sp)
+ {
+ lldb::tid_t old_thread_id = old_thread_sp->GetID();
+ m_thread_id_to_index_id_map.erase(old_thread_id);
+ }
+ }
+
return true;
}
@@ -1740,103 +1684,10 @@ ProcessGDBRemote::DoHalt (bool &caused_s
}
Error
-ProcessGDBRemote::InterruptIfRunning
-(
- bool discard_thread_plans,
- bool catch_stop_event,
- EventSP &stop_event_sp
-)
-{
- Error error;
-
- LogSP log (ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_PROCESS));
-
- bool paused_private_state_thread = false;
- const bool is_running = m_gdb_comm.IsRunning();
- if (log)
- log->Printf ("ProcessGDBRemote::InterruptIfRunning(discard_thread_plans=%i, catch_stop_event=%i) is_running=%i",
- discard_thread_plans,
- catch_stop_event,
- is_running);
-
- if (discard_thread_plans)
- {
- if (log)
- log->Printf ("ProcessGDBRemote::InterruptIfRunning() discarding all thread plans");
- m_thread_list.DiscardThreadPlans();
- }
- if (is_running)
- {
- if (catch_stop_event)
- {
- if (log)
- log->Printf ("ProcessGDBRemote::InterruptIfRunning() pausing private state thread");
- PausePrivateStateThread();
- paused_private_state_thread = true;
- }
-
- bool timed_out = false;
- Mutex::Locker locker;
-
- if (!m_gdb_comm.SendInterrupt (locker, 1, timed_out))
- {
- if (timed_out)
- error.SetErrorString("timed out sending interrupt packet");
- else
- error.SetErrorString("unknown error sending interrupt packet");
- if (paused_private_state_thread)
- ResumePrivateStateThread();
- return error;
- }
-
- if (catch_stop_event)
- {
- // LISTEN HERE
- TimeValue timeout_time;
- timeout_time = TimeValue::Now();
- timeout_time.OffsetWithSeconds(5);
- StateType state = WaitForStateChangedEventsPrivate (&timeout_time, stop_event_sp);
-
- timed_out = state == eStateInvalid;
- if (log)
- log->Printf ("ProcessGDBRemote::InterruptIfRunning() catch stop event: state = %s, timed-out=%i", StateAsCString(state), timed_out);
-
- if (timed_out)
- error.SetErrorString("unable to verify target stopped");
- }
-
- if (paused_private_state_thread)
- {
- if (log)
- log->Printf ("ProcessGDBRemote::InterruptIfRunning() resuming private state thread");
- ResumePrivateStateThread();
- }
- }
- return error;
-}
-
-Error
-ProcessGDBRemote::WillDetach ()
-{
- LogSP log (ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_PROCESS));
- if (log)
- log->Printf ("ProcessGDBRemote::WillDetach()");
-
- bool discard_thread_plans = true;
- bool catch_stop_event = true;
- EventSP event_sp;
-
- // FIXME: InterruptIfRunning should be done in the Process base class, or better still make Halt do what is
- // needed. This shouldn't be a feature of a particular plugin.
-
- return InterruptIfRunning (discard_thread_plans, catch_stop_event, event_sp);
-}
-
-Error
ProcessGDBRemote::DoDetach()
{
Error error;
- LogSP log (ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_PROCESS));
+ Log *log (ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_PROCESS));
if (log)
log->Printf ("ProcessGDBRemote::DoDetach()");
@@ -1867,7 +1718,7 @@ Error
ProcessGDBRemote::DoDestroy ()
{
Error error;
- LogSP log (ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_PROCESS));
+ Log *log (ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_PROCESS));
if (log)
log->Printf ("ProcessGDBRemote::DoDestroy()");
@@ -2050,15 +1901,9 @@ ProcessGDBRemote::IsAlive ()
return m_gdb_comm.IsConnected() && m_private_state.GetValue() != eStateExited;
}
-// For kernel debugging, we return the load address of the kernel binary as the
-// ImageInfoAddress and we return the DynamicLoaderDarwinKernel as the GetDynamicLoader()
-// name so the correct DynamicLoader plugin is chosen.
addr_t
ProcessGDBRemote::GetImageInfoAddress()
{
- if (m_kernel_load_addr != LLDB_INVALID_ADDRESS)
- return m_kernel_load_addr;
- else
return m_gdb_comm.GetShlibInfoAddr();
}
@@ -2251,21 +2096,21 @@ ProcessGDBRemote::PutSTDIN (const char *
}
Error
-ProcessGDBRemote::EnableBreakpoint (BreakpointSite *bp_site)
+ProcessGDBRemote::EnableBreakpointSite (BreakpointSite *bp_site)
{
Error error;
assert (bp_site != NULL);
- LogSP log (ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_BREAKPOINTS));
+ Log *log (ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_BREAKPOINTS));
user_id_t site_id = bp_site->GetID();
const addr_t addr = bp_site->GetLoadAddress();
if (log)
- log->Printf ("ProcessGDBRemote::EnableBreakpoint (size_id = %" PRIu64 ") address = 0x%" PRIx64, site_id, (uint64_t)addr);
+ log->Printf ("ProcessGDBRemote::EnableBreakpointSite (size_id = %" PRIu64 ") address = 0x%" PRIx64, site_id, (uint64_t)addr);
if (bp_site->IsEnabled())
{
if (log)
- log->Printf ("ProcessGDBRemote::EnableBreakpoint (size_id = %" PRIu64 ") address = 0x%" PRIx64 " -- SUCCESS (already enabled)", site_id, (uint64_t)addr);
+ log->Printf ("ProcessGDBRemote::EnableBreakpointSite (size_id = %" PRIu64 ") address = 0x%" PRIx64 " -- SUCCESS (already enabled)", site_id, (uint64_t)addr);
return error;
}
else
@@ -2303,7 +2148,7 @@ ProcessGDBRemote::EnableBreakpoint (Brea
if (log)
{
const char *err_string = error.AsCString();
- log->Printf ("ProcessGDBRemote::EnableBreakpoint() error for breakpoint at 0x%8.8" PRIx64 ": %s",
+ log->Printf ("ProcessGDBRemote::EnableBreakpointSite () error for breakpoint at 0x%8.8" PRIx64 ": %s",
bp_site->GetLoadAddress(),
err_string ? err_string : "NULL");
}
@@ -2314,15 +2159,15 @@ ProcessGDBRemote::EnableBreakpoint (Brea
}
Error
-ProcessGDBRemote::DisableBreakpoint (BreakpointSite *bp_site)
+ProcessGDBRemote::DisableBreakpointSite (BreakpointSite *bp_site)
{
Error error;
assert (bp_site != NULL);
addr_t addr = bp_site->GetLoadAddress();
user_id_t site_id = bp_site->GetID();
- LogSP log (ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_BREAKPOINTS));
+ Log *log (ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_BREAKPOINTS));
if (log)
- log->Printf ("ProcessGDBRemote::DisableBreakpoint (site_id = %" PRIu64 ") addr = 0x%8.8" PRIx64, site_id, (uint64_t)addr);
+ log->Printf ("ProcessGDBRemote::DisableBreakpointSite (site_id = %" PRIu64 ") addr = 0x%8.8" PRIx64, site_id, (uint64_t)addr);
if (bp_site->IsEnabled())
{
@@ -2351,7 +2196,7 @@ ProcessGDBRemote::DisableBreakpoint (Bre
else
{
if (log)
- log->Printf ("ProcessGDBRemote::DisableBreakpoint (site_id = %" PRIu64 ") addr = 0x%8.8" PRIx64 " -- SUCCESS (already disabled)", site_id, (uint64_t)addr);
+ log->Printf ("ProcessGDBRemote::DisableBreakpointSite (site_id = %" PRIu64 ") addr = 0x%8.8" PRIx64 " -- SUCCESS (already disabled)", site_id, (uint64_t)addr);
return error;
}
@@ -2386,7 +2231,7 @@ ProcessGDBRemote::EnableWatchpoint (Watc
{
user_id_t watchID = wp->GetID();
addr_t addr = wp->GetLoadAddress();
- LogSP log (ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_WATCHPOINTS));
+ Log *log (ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_WATCHPOINTS));
if (log)
log->Printf ("ProcessGDBRemote::EnableWatchpoint(watchID = %" PRIu64 ")", watchID);
if (wp->IsEnabled())
@@ -2428,7 +2273,7 @@ ProcessGDBRemote::DisableWatchpoint (Wat
{
user_id_t watchID = wp->GetID();
- LogSP log (ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_WATCHPOINTS));
+ Log *log (ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_WATCHPOINTS));
addr_t addr = wp->GetLoadAddress();
@@ -2480,7 +2325,7 @@ Error
ProcessGDBRemote::DoSignal (int signo)
{
Error error;
- LogSP log (ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_PROCESS));
+ Log *log (ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_PROCESS));
if (log)
log->Printf ("ProcessGDBRemote::DoSignal (signal = %d)", signo);
@@ -2543,7 +2388,7 @@ ProcessGDBRemote::StartDebugserverProces
m_stdio_communication.Clear();
- LogSP log (ProcessGDBRemoteLog::GetLogIfAllCategoriesSet (GDBR_LOG_PROCESS));
+ Log *log (ProcessGDBRemoteLog::GetLogIfAllCategoriesSet (GDBR_LOG_PROCESS));
Args &debugserver_args = debugserver_launch_info.GetArguments();
char arg_cstr[PATH_MAX];
@@ -2632,7 +2477,7 @@ ProcessGDBRemote::StartDebugserverProces
m_debugserver_pid = LLDB_INVALID_PROCESS_ID;
if (error.Fail() || log)
- error.PutToLog(log.get(), "Host::LaunchProcess (launch_info) => pid=%" PRIu64 ", path='%s'", m_debugserver_pid, debugserver_path);
+ error.PutToLog(log, "Host::LaunchProcess (launch_info) => pid=%" PRIu64 ", path='%s'", m_debugserver_pid, debugserver_path);
}
else
{
@@ -2667,7 +2512,7 @@ ProcessGDBRemote::MonitorDebugserverProc
// "debugserver_pid" argument passed in is the process ID for
// debugserver that we are tracking...
- LogSP log (ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_PROCESS));
+ Log *log (ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_PROCESS));
ProcessGDBRemote *process = (ProcessGDBRemote *)callback_baton;
@@ -2772,7 +2617,7 @@ ProcessGDBRemote::Initialize()
bool
ProcessGDBRemote::StartAsyncThread ()
{
- LogSP log (ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_PROCESS));
+ Log *log (ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_PROCESS));
if (log)
log->Printf ("ProcessGDBRemote::%s ()", __FUNCTION__);
@@ -2807,7 +2652,7 @@ ProcessGDBRemote::StartAsyncThread ()
void
ProcessGDBRemote::StopAsyncThread ()
{
- LogSP log (ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_PROCESS));
+ Log *log (ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_PROCESS));
if (log)
log->Printf ("ProcessGDBRemote::%s ()", __FUNCTION__);
@@ -2840,7 +2685,7 @@ ProcessGDBRemote::AsyncThread (void *arg
{
ProcessGDBRemote *process = (ProcessGDBRemote*) arg;
- LogSP log (ProcessGDBRemoteLog::GetLogIfAllCategoriesSet (GDBR_LOG_PROCESS));
+ Log *log (ProcessGDBRemoteLog::GetLogIfAllCategoriesSet (GDBR_LOG_PROCESS));
if (log)
log->Printf ("ProcessGDBRemote::%s (arg = %p, pid = %" PRIu64 ") thread starting...", __FUNCTION__, arg, process->GetID());
@@ -3010,7 +2855,7 @@ ProcessGDBRemote::GetDispatchQueueNameFo
Error error;
if (ReadMemory (m_dispatch_queue_offsets_addr, memory_buffer, sizeof(dispatch_queue_offsets), error) == sizeof(dispatch_queue_offsets))
{
- uint32_t data_offset = 0;
+ lldb::offset_t data_offset = 0;
if (data.GetU16(&data_offset, &dispatch_queue_offsets.dqo_version, sizeof(dispatch_queue_offsets)/sizeof(uint16_t)))
{
if (ReadMemory (thread_dispatch_qaddr, &memory_buffer, data.GetAddressByteSize(), error) == data.GetAddressByteSize())
@@ -3073,7 +2918,7 @@ ProcessGDBRemote::NewThreadNotifyBreakpo
{
// I don't think I have to do anything here, just make sure I notice the new thread when it starts to
// run so I can stop it if that's what I want to do.
- LogSP log (lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP));
+ Log *log (lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP));
if (log)
log->Printf("Hit New Thread Notification breakpoint.");
return false;
@@ -3083,7 +2928,7 @@ ProcessGDBRemote::NewThreadNotifyBreakpo
bool
ProcessGDBRemote::StartNoticingNewThreads()
{
- LogSP log (lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP));
+ Log *log (lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP));
if (m_thread_create_bp_sp)
{
if (log && log->GetVerbose())
@@ -3115,7 +2960,7 @@ ProcessGDBRemote::StartNoticingNewThread
bool
ProcessGDBRemote::StopNoticingNewThreads()
{
- LogSP log (lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP));
+ Log *log (lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP));
if (log && log->GetVerbose())
log->Printf ("Disabling new thread notification breakpoint.");
@@ -3215,7 +3060,13 @@ public:
result.SetStatus (eReturnStatusSuccessFinishResult);
Stream &output_strm = result.GetOutputStream();
output_strm.Printf (" packet: %s\n", packet_cstr);
- const std::string &response_str = response.GetStringRef();
+ std::string &response_str = response.GetStringRef();
+
+ if (strcmp(packet_cstr, "qGetProfileData") == 0)
+ {
+ response_str = process->GetGDBRemote().HarmonizeThreadIdsForProfileData(process, response);
+ }
+
if (response_str.empty())
output_strm.PutCString ("response: \nerror: UNIMPLEMENTED\n");
else
@@ -3226,6 +3077,59 @@ public:
}
};
+class CommandObjectProcessGDBRemotePacketMonitor : public CommandObjectRaw
+{
+private:
+
+public:
+ CommandObjectProcessGDBRemotePacketMonitor(CommandInterpreter &interpreter) :
+ CommandObjectRaw (interpreter,
+ "process plugin packet monitor",
+ "Send a qRcmd packet through the GDB remote protocol and print the response."
+ "The argument passed to this command will be hex encoded into a valid 'qRcmd' packet, sent and the response will be printed.",
+ NULL)
+ {
+ }
+
+ ~CommandObjectProcessGDBRemotePacketMonitor ()
+ {
+ }
+
+ bool
+ DoExecute (const char *command, CommandReturnObject &result)
+ {
+ if (command == NULL || command[0] == '\0')
+ {
+ result.AppendErrorWithFormat ("'%s' takes a command string argument", m_cmd_name.c_str());
+ result.SetStatus (eReturnStatusFailed);
+ return false;
+ }
+
+ ProcessGDBRemote *process = (ProcessGDBRemote *)m_interpreter.GetExecutionContext().GetProcessPtr();
+ if (process)
+ {
+ StreamString packet;
+ packet.PutCString("qRcmd,");
+ packet.PutBytesAsRawHex8(command, strlen(command));
+ const char *packet_cstr = packet.GetString().c_str();
+
+ bool send_async = true;
+ StringExtractorGDBRemote response;
+ process->GetGDBRemote().SendPacketAndWaitForResponse(packet_cstr, response, send_async);
+ result.SetStatus (eReturnStatusSuccessFinishResult);
+ Stream &output_strm = result.GetOutputStream();
+ output_strm.Printf (" packet: %s\n", packet_cstr);
+ const std::string &response_str = response.GetStringRef();
+
+ if (response_str.empty())
+ output_strm.PutCString ("response: \nerror: UNIMPLEMENTED\n");
+ else
+ output_strm.Printf ("response: %s\n", response.GetStringRef().c_str());
+ }
+ return true;
+ }
+};
+
class CommandObjectProcessGDBRemotePacket : public CommandObjectMultiword
{
private:
@@ -3239,6 +3143,7 @@ public:
{
LoadSubCommand ("history", CommandObjectSP (new CommandObjectProcessGDBRemotePacketHistory (interpreter)));
LoadSubCommand ("send", CommandObjectSP (new CommandObjectProcessGDBRemotePacketSend (interpreter)));
+ LoadSubCommand ("monitor", CommandObjectSP (new CommandObjectProcessGDBRemotePacketMonitor (interpreter)));
}
~CommandObjectProcessGDBRemotePacket ()
Modified: lldb/branches/windows/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/windows/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h?rev=179679&r1=179678&r2=179679&view=diff
==============================================================================
--- lldb/branches/windows/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h (original)
+++ lldb/branches/windows/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h Wed Apr 17 03:38:48 2013
@@ -141,10 +141,10 @@ public:
DoHalt (bool &caused_stop);
virtual lldb_private::Error
- WillDetach ();
-
- virtual lldb_private::Error
DoDetach ();
+
+ virtual bool
+ DetachRequiresHalt() { return true; }
virtual lldb_private::Error
DoSignal (int signal);
@@ -193,10 +193,10 @@ public:
// Process Breakpoints
//----------------------------------------------------------------------
virtual lldb_private::Error
- EnableBreakpoint (lldb_private::BreakpointSite *bp_site);
+ EnableBreakpointSite (lldb_private::BreakpointSite *bp_site);
virtual lldb_private::Error
- DisableBreakpoint (lldb_private::BreakpointSite *bp_site);
+ DisableBreakpointSite (lldb_private::BreakpointSite *bp_site);
//----------------------------------------------------------------------
// Process Watchpoints
@@ -297,9 +297,6 @@ protected:
m_last_stop_packet = response;
}
- void
- CheckForKernel (lldb_private::Stream *strm);
-
//------------------------------------------------------------------
/// Broadcaster event bits definitions.
//------------------------------------------------------------------
@@ -342,7 +339,6 @@ protected:
bool m_waiting_for_attach;
bool m_destroy_tried_resuming;
std::string m_dyld_plugin_name;
- lldb::addr_t m_kernel_load_addr;
lldb::CommandObjectSP m_command_sp;
bool
@@ -387,11 +383,6 @@ protected:
const char *bytes,
size_t bytes_len);
- lldb_private::Error
- InterruptIfRunning (bool discard_thread_plans,
- bool catch_stop_event,
- lldb::EventSP &stop_event_sp);
-
lldb_private::DynamicLoader *
GetDynamicLoader ();
Modified: lldb/branches/windows/source/Plugins/Process/gdb-remote/ProcessGDBRemoteLog.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/windows/source/Plugins/Process/gdb-remote/ProcessGDBRemoteLog.cpp?rev=179679&r1=179678&r2=179679&view=diff
==============================================================================
--- lldb/branches/windows/source/Plugins/Process/gdb-remote/ProcessGDBRemoteLog.cpp (original)
+++ lldb/branches/windows/source/Plugins/Process/gdb-remote/ProcessGDBRemoteLog.cpp Wed Apr 17 03:38:48 2013
@@ -22,39 +22,43 @@ using namespace lldb_private;
// control access to our static g_log_sp by hiding it in a singleton function
// that will construct the static g_lob_sp the first time this function is
// called.
-static LogSP &
+static bool g_log_enabled = false;
+static Log * g_log = NULL;
+static Log *
GetLog ()
{
- static LogSP g_log_sp;
- return g_log_sp;
+ if (!g_log_enabled)
+ return NULL;
+ return g_log;
}
-LogSP
+
+Log *
ProcessGDBRemoteLog::GetLogIfAllCategoriesSet (uint32_t mask)
{
- LogSP log(GetLog ());
+ Log *log(GetLog ());
if (log && mask)
{
uint32_t log_mask = log->GetMask().Get();
if ((log_mask & mask) != mask)
- return LogSP();
+ return NULL;
}
return log;
}
-LogSP
+Log *
ProcessGDBRemoteLog::GetLogIfAnyCategoryIsSet (uint32_t mask)
{
- LogSP log(GetLog ());
+ Log *log(GetLog ());
if (log && log->GetMask().Get() & mask)
return log;
- return LogSP();
+ return NULL;
}
void
ProcessGDBRemoteLog::DisableLog (const char **categories, Stream *feedback_strm)
{
- LogSP log (GetLog ());
+ Log *log (GetLog ());
if (log)
{
uint32_t flag_bits = 0;
@@ -91,7 +95,7 @@ ProcessGDBRemoteLog::DisableLog (const c
}
if (flag_bits == 0)
- GetLog ().reset();
+ g_log_enabled = false;
else
log->GetMask().Reset (flag_bits);
}
@@ -99,24 +103,25 @@ ProcessGDBRemoteLog::DisableLog (const c
return;
}
-LogSP
+Log *
ProcessGDBRemoteLog::EnableLog (StreamSP &log_stream_sp, uint32_t log_options, const char **categories, Stream *feedback_strm)
{
// Try see if there already is a log - that way we can reuse its settings.
// We could reuse the log in toto, but we don't know that the stream is the same.
uint32_t flag_bits = 0;
- LogSP log(GetLog ());
- if (log)
- flag_bits = log->GetMask().Get();
+ if (g_log)
+ flag_bits = g_log->GetMask().Get();
// Now make a new log with this stream if one was provided
if (log_stream_sp)
{
- log.reset (new Log(log_stream_sp));
- GetLog () = log;
+ if (g_log)
+ g_log->SetStream(log_stream_sp);
+ else
+ g_log = new Log(log_stream_sp);
}
- if (log)
+ if (g_log)
{
bool got_unknown_category = false;
for (size_t i=0; categories[i] != NULL; ++i)
@@ -149,10 +154,11 @@ ProcessGDBRemoteLog::EnableLog (StreamSP
}
if (flag_bits == 0)
flag_bits = GDBR_LOG_DEFAULT;
- log->GetMask().Reset(flag_bits);
- log->GetOptions().Reset(log_options);
+ g_log->GetMask().Reset(flag_bits);
+ g_log->GetOptions().Reset(log_options);
}
- return log;
+ g_log_enabled = true;
+ return g_log;
}
void
@@ -179,7 +185,7 @@ ProcessGDBRemoteLog::ListLogCategories (
void
ProcessGDBRemoteLog::LogIf (uint32_t mask, const char *format, ...)
{
- LogSP log (ProcessGDBRemoteLog::GetLogIfAllCategoriesSet (mask));
+ Log *log (ProcessGDBRemoteLog::GetLogIfAllCategoriesSet (mask));
if (log)
{
va_list args;
Modified: lldb/branches/windows/source/Plugins/Process/gdb-remote/ProcessGDBRemoteLog.h
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/windows/source/Plugins/Process/gdb-remote/ProcessGDBRemoteLog.h?rev=179679&r1=179678&r2=179679&view=diff
==============================================================================
--- lldb/branches/windows/source/Plugins/Process/gdb-remote/ProcessGDBRemoteLog.h (original)
+++ lldb/branches/windows/source/Plugins/Process/gdb-remote/ProcessGDBRemoteLog.h Wed Apr 17 03:38:48 2013
@@ -35,16 +35,16 @@
class ProcessGDBRemoteLog
{
public:
- static lldb::LogSP
+ static lldb_private::Log *
GetLogIfAllCategoriesSet(uint32_t mask = 0);
- static lldb::LogSP
+ static lldb_private::Log *
GetLogIfAnyCategoryIsSet (uint32_t mask);
static void
DisableLog (const char **categories, lldb_private::Stream *feedback_strm);
- static lldb::LogSP
+ static lldb_private::Log *
EnableLog (lldb::StreamSP &log_stream_sp, uint32_t log_options, const char **categories, lldb_private::Stream *feedback_strm);
static void
Modified: lldb/branches/windows/source/Plugins/Process/gdb-remote/ThreadGDBRemote.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/windows/source/Plugins/Process/gdb-remote/ThreadGDBRemote.cpp?rev=179679&r1=179678&r2=179679&view=diff
==============================================================================
--- lldb/branches/windows/source/Plugins/Process/gdb-remote/ThreadGDBRemote.cpp (original)
+++ lldb/branches/windows/source/Plugins/Process/gdb-remote/ThreadGDBRemote.cpp Wed Apr 17 03:38:48 2013
@@ -95,7 +95,7 @@ ThreadGDBRemote::WillResume (StateType r
ClearStackFrames();
int signo = GetResumeSignal();
- lldb::LogSP log(lldb_private::GetLogIfAnyCategoriesSet (GDBR_LOG_THREAD));
+ Log *log(lldb_private::GetLogIfAnyCategoriesSet (GDBR_LOG_THREAD));
if (log)
log->Printf ("Resuming thread: %4.4" PRIx64 " with state: %s.", GetID(), StateAsCString(resume_state));
@@ -202,8 +202,12 @@ ThreadGDBRemote::CreateRegisterContextFo
reg_ctx_sp.reset (new GDBRemoteRegisterContext (*this, concrete_frame_idx, gdb_process->m_register_info, read_all_registers_at_once));
}
}
- else if (m_unwinder_ap.get())
- reg_ctx_sp = m_unwinder_ap->CreateRegisterContextForFrame (frame);
+ else
+ {
+ Unwind *unwinder = GetUnwinder ();
+ if (unwinder)
+ reg_ctx_sp = unwinder->CreateRegisterContextForFrame (frame);
+ }
return reg_ctx_sp;
}
Modified: lldb/branches/windows/source/Plugins/Process/mach-core/ProcessMachCore.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/windows/source/Plugins/Process/mach-core/ProcessMachCore.cpp?rev=179679&r1=179678&r2=179679&view=diff
==============================================================================
--- lldb/branches/windows/source/Plugins/Process/mach-core/ProcessMachCore.cpp (original)
+++ lldb/branches/windows/source/Plugins/Process/mach-core/ProcessMachCore.cpp Wed Apr 17 03:38:48 2013
@@ -301,24 +301,12 @@ ProcessMachCore::DoLoadCore ()
if (m_dyld_addr == LLDB_INVALID_ADDRESS)
{
- // Check the magic kernel address for the mach image header address in case
- // it is there.
- if (arch.GetAddressByteSize() == 8)
+ addr_t kernel_load_address = DynamicLoaderDarwinKernel::SearchForDarwinKernel (this);
+ if (kernel_load_address != LLDB_INVALID_ADDRESS)
{
- Error header_addr_error;
- addr_t header_addr = ReadPointerFromMemory (0xffffff8000002010ull, header_addr_error);
- if (header_addr != LLDB_INVALID_ADDRESS)
- GetDynamicLoaderAddress (header_addr);
- }
- else
- {
- Error header_addr_error;
- addr_t header_addr = ReadPointerFromMemory (0xffff0110, header_addr_error);
- if (header_addr != LLDB_INVALID_ADDRESS)
- GetDynamicLoaderAddress (header_addr);
+ GetDynamicLoaderAddress (kernel_load_address);
}
}
-
return error;
}
Modified: lldb/branches/windows/source/Plugins/Process/mach-core/ProcessMachCore.h
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/windows/source/Plugins/Process/mach-core/ProcessMachCore.h?rev=179679&r1=179678&r2=179679&view=diff
==============================================================================
--- lldb/branches/windows/source/Plugins/Process/mach-core/ProcessMachCore.h (original)
+++ lldb/branches/windows/source/Plugins/Process/mach-core/ProcessMachCore.h Wed Apr 17 03:38:48 2013
@@ -130,7 +130,7 @@ private:
// For ProcessMachCore only
//------------------------------------------------------------------
typedef lldb_private::Range<uint32_t, uint32_t> FileRange;
- typedef lldb_private::RangeDataArray<lldb::addr_t, lldb::addr_t, FileRange, 1> VMRangeToFileOffset;
+ typedef lldb_private::RangeDataVector<lldb::addr_t, lldb::addr_t, FileRange> VMRangeToFileOffset;
VMRangeToFileOffset m_core_aranges;
lldb::ModuleSP m_core_module_sp;
Modified: lldb/branches/windows/source/Plugins/Process/mach-core/ThreadMachCore.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/windows/source/Plugins/Process/mach-core/ThreadMachCore.cpp?rev=179679&r1=179678&r2=179679&view=diff
==============================================================================
--- lldb/branches/windows/source/Plugins/Process/mach-core/ThreadMachCore.cpp (original)
+++ lldb/branches/windows/source/Plugins/Process/mach-core/ThreadMachCore.cpp Wed Apr 17 03:38:48 2013
@@ -118,9 +118,11 @@ ThreadMachCore::CreateRegisterContextFor
}
reg_ctx_sp = m_thread_reg_ctx_sp;
}
- else if (m_unwinder_ap.get())
+ else
{
- reg_ctx_sp = m_unwinder_ap->CreateRegisterContextForFrame (frame);
+ Unwind *unwinder = GetUnwinder ();
+ if (unwinder)
+ reg_ctx_sp = unwinder->CreateRegisterContextForFrame (frame);
}
return reg_ctx_sp;
}
Modified: lldb/branches/windows/source/Plugins/SymbolFile/DWARF/DWARFAbbreviationDeclaration.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/windows/source/Plugins/SymbolFile/DWARF/DWARFAbbreviationDeclaration.cpp?rev=179679&r1=179678&r2=179679&view=diff
==============================================================================
--- lldb/branches/windows/source/Plugins/SymbolFile/DWARF/DWARFAbbreviationDeclaration.cpp (original)
+++ lldb/branches/windows/source/Plugins/SymbolFile/DWARF/DWARFAbbreviationDeclaration.cpp Wed Apr 17 03:38:48 2013
@@ -32,13 +32,13 @@ DWARFAbbreviationDeclaration::DWARFAbbre
}
bool
-DWARFAbbreviationDeclaration::Extract(const DataExtractor& data, uint32_t* offset_ptr)
+DWARFAbbreviationDeclaration::Extract(const DataExtractor& data, lldb::offset_t* offset_ptr)
{
return Extract(data, offset_ptr, data.GetULEB128(offset_ptr));
}
bool
-DWARFAbbreviationDeclaration::Extract(const DataExtractor& data, uint32_t* offset_ptr, dw_uleb128_t code)
+DWARFAbbreviationDeclaration::Extract(const DataExtractor& data, lldb::offset_t *offset_ptr, dw_uleb128_t code)
{
m_code = code;
m_attributes.clear();
@@ -155,7 +155,7 @@ DWARFAbbreviationDeclaration::CopyChangi
dw_attr_t attr;
dw_form_t form;
uint32_t i;
- dw_offset_t offset = debug_info_offset;
+ lldb::offset_t offset = debug_info_offset;
for (i = 0; i < num_abbr_decl_attributes; ++i)
{
Modified: lldb/branches/windows/source/Plugins/SymbolFile/DWARF/DWARFAbbreviationDeclaration.h
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/windows/source/Plugins/SymbolFile/DWARF/DWARFAbbreviationDeclaration.h?rev=179679&r1=179678&r2=179679&view=diff
==============================================================================
--- lldb/branches/windows/source/Plugins/SymbolFile/DWARF/DWARFAbbreviationDeclaration.h (original)
+++ lldb/branches/windows/source/Plugins/SymbolFile/DWARF/DWARFAbbreviationDeclaration.h Wed Apr 17 03:38:48 2013
@@ -32,7 +32,7 @@ public:
void SetCode(dw_uleb128_t code) { m_code = code; }
dw_tag_t Tag() const { return m_tag; }
bool HasChildren() const { return m_has_children; }
- uint32_t NumAttributes() const { return m_attributes.size(); }
+ size_t NumAttributes() const { return m_attributes.size(); }
dw_attr_t GetAttrByIndex(uint32_t idx) const { return m_attributes.size() > idx ? m_attributes[idx].get_attr() : 0; }
dw_form_t GetFormByIndex(uint32_t idx) const { return m_attributes.size() > idx ? m_attributes[idx].get_form() : 0; }
bool GetAttrAndFormByIndex(uint32_t idx, dw_attr_t& attr, dw_form_t& form) const
@@ -63,8 +63,8 @@ public:
const DWARFCompileUnit* cu,
const uint32_t strp_min_len);
uint32_t FindAttributeIndex(dw_attr_t attr) const;
- bool Extract(const lldb_private::DataExtractor& data, uint32_t* offset_ptr);
- bool Extract(const lldb_private::DataExtractor& data, uint32_t* offset_ptr, dw_uleb128_t code);
+ bool Extract(const lldb_private::DataExtractor& data, lldb::offset_t *offset_ptr);
+ bool Extract(const lldb_private::DataExtractor& data, lldb::offset_t *offset_ptr, dw_uleb128_t code);
// void Append(BinaryStreamBuf& out_buff) const;
bool IsValid();
void Dump(lldb_private::Stream *s) const;
Modified: lldb/branches/windows/source/Plugins/SymbolFile/DWARF/DWARFAttribute.h
URL: http://llvm.org/viewvc/llvm-project/lldb/branches/windows/source/Plugins/SymbolFile/DWARF/DWARFAttribute.h?rev=179679&r1=179678&r2=179679&view=diff
==============================================================================
--- lldb/branches/windows/source/Plugins/SymbolFile/DWARF/DWARFAttribute.h (original)
+++ lldb/branches/windows/source/Plugins/SymbolFile/DWARF/DWARFAttribute.h Wed Apr 17 03:38:48 2013
@@ -25,12 +25,12 @@ public:
void set_attr(dw_attr_t attr) { m_attr_form = (m_attr_form & 0x0000ffffu) | (attr << 16); }
void set_form(dw_form_t form) { m_attr_form = (m_attr_form & 0xffff0000u) | form; }
dw_attr_t get_attr() const { return m_attr_form >> 16; }
- dw_form_t get_form() const { return m_attr_form; }
+ dw_form_t get_form() const { return (dw_form_t)m_attr_form; }
void get(dw_attr_t& attr, dw_form_t& form) const
{
register uint32_t attr_form = m_attr_form;
attr = attr_form >> 16;
- form = attr_form;
+ form = (dw_form_t)attr_form;
}
bool operator == (const DWARFAttribute& rhs) const { return m_attr_form == rhs.m_attr_form; }
typedef std::vector<DWARFAttribute> collection;
More information about the llvm-branch-commits
mailing list