diff options
author | Greg Clayton <gclayton@apple.com> | 2013-01-09 19:44:40 +0000 |
---|---|---|
committer | Greg Clayton <gclayton@apple.com> | 2013-01-09 19:44:40 +0000 |
commit | f9fc609fe7e246f98ba72818af1827a269cf71ee (patch) | |
tree | 676a461898bf2f4feef048d3254f326973b68064 /lldb/source/Commands/CommandObjectRegister.cpp | |
parent | eb9ae768647ee4280e4f25d58180067e1ed3c5ab (diff) | |
download | bcm5719-llvm-f9fc609fe7e246f98ba72818af1827a269cf71ee.tar.gz bcm5719-llvm-f9fc609fe7e246f98ba72818af1827a269cf71ee.zip |
Expanded the flags that can be set for a command object in lldb_private::CommandObject. This list of available flags are:
enum
{
//----------------------------------------------------------------------
// eFlagRequiresTarget
//
// Ensures a valid target is contained in m_exe_ctx prior to executing
// the command. If a target doesn't exist or is invalid, the command
// will fail and CommandObject::GetInvalidTargetDescription() will be
// returned as the error. CommandObject subclasses can override the
// virtual function for GetInvalidTargetDescription() to provide custom
// strings when needed.
//----------------------------------------------------------------------
eFlagRequiresTarget = (1u << 0),
//----------------------------------------------------------------------
// eFlagRequiresProcess
//
// Ensures a valid process is contained in m_exe_ctx prior to executing
// the command. If a process doesn't exist or is invalid, the command
// will fail and CommandObject::GetInvalidProcessDescription() will be
// returned as the error. CommandObject subclasses can override the
// virtual function for GetInvalidProcessDescription() to provide custom
// strings when needed.
//----------------------------------------------------------------------
eFlagRequiresProcess = (1u << 1),
//----------------------------------------------------------------------
// eFlagRequiresThread
//
// Ensures a valid thread is contained in m_exe_ctx prior to executing
// the command. If a thread doesn't exist or is invalid, the command
// will fail and CommandObject::GetInvalidThreadDescription() will be
// returned as the error. CommandObject subclasses can override the
// virtual function for GetInvalidThreadDescription() to provide custom
// strings when needed.
//----------------------------------------------------------------------
eFlagRequiresThread = (1u << 2),
//----------------------------------------------------------------------
// eFlagRequiresFrame
//
// Ensures a valid frame is contained in m_exe_ctx prior to executing
// the command. If a frame doesn't exist or is invalid, the command
// will fail and CommandObject::GetInvalidFrameDescription() will be
// returned as the error. CommandObject subclasses can override the
// virtual function for GetInvalidFrameDescription() to provide custom
// strings when needed.
//----------------------------------------------------------------------
eFlagRequiresFrame = (1u << 3),
//----------------------------------------------------------------------
// eFlagRequiresRegContext
//
// Ensures a valid register context (from the selected frame if there
// is a frame in m_exe_ctx, or from the selected thread from m_exe_ctx)
// is availble from m_exe_ctx prior to executing the command. If a
// target doesn't exist or is invalid, the command will fail and
// CommandObject::GetInvalidRegContextDescription() will be returned as
// the error. CommandObject subclasses can override the virtual function
// for GetInvalidRegContextDescription() to provide custom strings when
// needed.
//----------------------------------------------------------------------
eFlagRequiresRegContext = (1u << 4),
//----------------------------------------------------------------------
// eFlagTryTargetAPILock
//
// Attempts to acquire the target lock if a target is selected in the
// command interpreter. If the command object fails to acquire the API
// lock, the command will fail with an appropriate error message.
//----------------------------------------------------------------------
eFlagTryTargetAPILock = (1u << 5),
//----------------------------------------------------------------------
// eFlagProcessMustBeLaunched
//
// Verifies that there is a launched process in m_exe_ctx, if there
// isn't, the command will fail with an appropriate error message.
//----------------------------------------------------------------------
eFlagProcessMustBeLaunched = (1u << 6),
//----------------------------------------------------------------------
// eFlagProcessMustBePaused
//
// Verifies that there is a paused process in m_exe_ctx, if there
// isn't, the command will fail with an appropriate error message.
//----------------------------------------------------------------------
eFlagProcessMustBePaused = (1u << 7)
};
Now each command object contains a "ExecutionContext m_exe_ctx;" member variable that gets initialized prior to running the command. The validity of the target objects in m_exe_ctx are checked to ensure that any target/process/thread/frame/reg context that are required are valid prior to executing the command. Each command object also contains a Mutex::Locker m_api_locker which gets used if eFlagTryTargetAPILock is set. This centralizes a lot of checking code that was previously and inconsistently implemented across many commands.
llvm-svn: 171990
Diffstat (limited to 'lldb/source/Commands/CommandObjectRegister.cpp')
-rw-r--r-- | lldb/source/Commands/CommandObjectRegister.cpp | 202 |
1 files changed, 95 insertions, 107 deletions
diff --git a/lldb/source/Commands/CommandObjectRegister.cpp b/lldb/source/Commands/CommandObjectRegister.cpp index e3e6f894128..db1c3af1862 100644 --- a/lldb/source/Commands/CommandObjectRegister.cpp +++ b/lldb/source/Commands/CommandObjectRegister.cpp @@ -45,7 +45,10 @@ public: "register read", "Dump the contents of one or more register values from the current frame. If no register is specified, dumps them all.", NULL, - eFlagProcessMustBeLaunched | eFlagProcessMustBePaused), + eFlagRequiresFrame | + eFlagRequiresRegContext | + eFlagProcessMustBeLaunched | + eFlagProcessMustBePaused ), m_option_group (interpreter), m_format_options (eFormatDefault), m_command_options () @@ -165,89 +168,80 @@ protected: DoExecute (Args& command, CommandReturnObject &result) { Stream &strm = result.GetOutputStream(); - ExecutionContext exe_ctx(m_interpreter.GetExecutionContext()); - RegisterContext *reg_ctx = exe_ctx.GetRegisterContext (); + RegisterContext *reg_ctx = m_exe_ctx.GetRegisterContext (); - if (reg_ctx) + const RegisterInfo *reg_info = NULL; + if (command.GetArgumentCount() == 0) { - const RegisterInfo *reg_info = NULL; - if (command.GetArgumentCount() == 0) + uint32_t set_idx; + + uint32_t num_register_sets = 1; + const uint32_t set_array_size = m_command_options.set_indexes.GetSize(); + if (set_array_size > 0) { - uint32_t set_idx; - - uint32_t num_register_sets = 1; - const uint32_t set_array_size = m_command_options.set_indexes.GetSize(); - if (set_array_size > 0) + for (uint32_t i=0; i<set_array_size; ++i) { - for (uint32_t i=0; i<set_array_size; ++i) + set_idx = m_command_options.set_indexes[i]->GetUInt64Value (UINT32_MAX, NULL); + if (set_idx != UINT32_MAX) { - set_idx = m_command_options.set_indexes[i]->GetUInt64Value (UINT32_MAX, NULL); - if (set_idx != UINT32_MAX) - { - if (!DumpRegisterSet (exe_ctx, strm, reg_ctx, set_idx)) - { - result.AppendErrorWithFormat ("invalid register set index: %u\n", set_idx); - result.SetStatus (eReturnStatusFailed); - break; - } - } - else + if (!DumpRegisterSet (m_exe_ctx, strm, reg_ctx, set_idx)) { - result.AppendError ("invalid register set index\n"); + result.AppendErrorWithFormat ("invalid register set index: %u\n", set_idx); result.SetStatus (eReturnStatusFailed); break; } } - } - else - { - if (m_command_options.dump_all_sets) - num_register_sets = reg_ctx->GetRegisterSetCount(); - - for (set_idx = 0; set_idx < num_register_sets; ++set_idx) + else { - // When dump_all_sets option is set, dump primitive as well as derived registers. - DumpRegisterSet (exe_ctx, strm, reg_ctx, set_idx, !m_command_options.dump_all_sets.GetCurrentValue()); + result.AppendError ("invalid register set index\n"); + result.SetStatus (eReturnStatusFailed); + break; } } } else { if (m_command_options.dump_all_sets) + num_register_sets = reg_ctx->GetRegisterSetCount(); + + for (set_idx = 0; set_idx < num_register_sets; ++set_idx) { - result.AppendError ("the --all option can't be used when registers names are supplied as arguments\n"); - result.SetStatus (eReturnStatusFailed); - } - else if (m_command_options.set_indexes.GetSize() > 0) - { - result.AppendError ("the --set <set> option can't be used when registers names are supplied as arguments\n"); - result.SetStatus (eReturnStatusFailed); + // When dump_all_sets option is set, dump primitive as well as derived registers. + DumpRegisterSet (m_exe_ctx, strm, reg_ctx, set_idx, !m_command_options.dump_all_sets.GetCurrentValue()); } - else + } + } + else + { + if (m_command_options.dump_all_sets) + { + result.AppendError ("the --all option can't be used when registers names are supplied as arguments\n"); + result.SetStatus (eReturnStatusFailed); + } + else if (m_command_options.set_indexes.GetSize() > 0) + { + result.AppendError ("the --set <set> option can't be used when registers names are supplied as arguments\n"); + result.SetStatus (eReturnStatusFailed); + } + else + { + const char *arg_cstr; + for (int arg_idx = 0; (arg_cstr = command.GetArgumentAtIndex(arg_idx)) != NULL; ++arg_idx) { - const char *arg_cstr; - for (int arg_idx = 0; (arg_cstr = command.GetArgumentAtIndex(arg_idx)) != NULL; ++arg_idx) - { - reg_info = reg_ctx->GetRegisterInfoByName(arg_cstr); + reg_info = reg_ctx->GetRegisterInfoByName(arg_cstr); - if (reg_info) - { - if (!DumpRegister (exe_ctx, strm, reg_ctx, reg_info)) - strm.Printf("%-12s = error: unavailable\n", reg_info->name); - } - else - { - result.AppendErrorWithFormat ("Invalid register name '%s'.\n", arg_cstr); - } + if (reg_info) + { + if (!DumpRegister (m_exe_ctx, strm, reg_ctx, reg_info)) + strm.Printf("%-12s = error: unavailable\n", reg_info->name); + } + else + { + result.AppendErrorWithFormat ("Invalid register name '%s'.\n", arg_cstr); } } } } - else - { - result.AppendError ("no current frame"); - result.SetStatus (eReturnStatusFailed); - } return result.Succeeded(); } @@ -366,7 +360,10 @@ public: "register write", "Modify a single register value.", NULL, - eFlagProcessMustBeLaunched | eFlagProcessMustBePaused) + eFlagRequiresFrame | + eFlagRequiresRegContext | + eFlagProcessMustBeLaunched | + eFlagProcessMustBePaused) { CommandArgumentEntry arg1; CommandArgumentEntry arg2; @@ -402,64 +399,55 @@ protected: DoExecute(Args& command, CommandReturnObject &result) { DataExtractor reg_data; - ExecutionContext exe_ctx(m_interpreter.GetExecutionContext()); - RegisterContext *reg_ctx = exe_ctx.GetRegisterContext (); + RegisterContext *reg_ctx = m_exe_ctx.GetRegisterContext (); - if (reg_ctx) + if (command.GetArgumentCount() != 2) { - if (command.GetArgumentCount() != 2) - { - result.AppendError ("register write takes exactly 2 arguments: <reg-name> <value>"); - result.SetStatus (eReturnStatusFailed); - } - else - { - const char *reg_name = command.GetArgumentAtIndex(0); - const char *value_str = command.GetArgumentAtIndex(1); - const RegisterInfo *reg_info = reg_ctx->GetRegisterInfoByName(reg_name); + result.AppendError ("register write takes exactly 2 arguments: <reg-name> <value>"); + result.SetStatus (eReturnStatusFailed); + } + else + { + const char *reg_name = command.GetArgumentAtIndex(0); + const char *value_str = command.GetArgumentAtIndex(1); + const RegisterInfo *reg_info = reg_ctx->GetRegisterInfoByName(reg_name); - if (reg_info) + if (reg_info) + { + RegisterValue reg_value; + + Error error (reg_value.SetValueFromCString (reg_info, value_str)); + if (error.Success()) { - RegisterValue reg_value; - - Error error (reg_value.SetValueFromCString (reg_info, value_str)); - if (error.Success()) - { - if (reg_ctx->WriteRegister (reg_info, reg_value)) - { - // Toss all frames and anything else in the thread - // after a register has been written. - exe_ctx.GetThreadRef().Flush(); - result.SetStatus (eReturnStatusSuccessFinishNoResult); - return true; - } - } - if (error.AsCString()) + if (reg_ctx->WriteRegister (reg_info, reg_value)) { - result.AppendErrorWithFormat ("Failed to write register '%s' with value '%s': %s\n", - reg_name, - value_str, - error.AsCString()); + // Toss all frames and anything else in the thread + // after a register has been written. + m_exe_ctx.GetThreadRef().Flush(); + result.SetStatus (eReturnStatusSuccessFinishNoResult); + return true; } - else - { - result.AppendErrorWithFormat ("Failed to write register '%s' with value '%s'", - reg_name, - value_str); - } - result.SetStatus (eReturnStatusFailed); + } + if (error.AsCString()) + { + result.AppendErrorWithFormat ("Failed to write register '%s' with value '%s': %s\n", + reg_name, + value_str, + error.AsCString()); } else { - result.AppendErrorWithFormat ("Register not found for '%s'.\n", reg_name); - result.SetStatus (eReturnStatusFailed); + result.AppendErrorWithFormat ("Failed to write register '%s' with value '%s'", + reg_name, + value_str); } + result.SetStatus (eReturnStatusFailed); + } + else + { + result.AppendErrorWithFormat ("Register not found for '%s'.\n", reg_name); + result.SetStatus (eReturnStatusFailed); } - } - else - { - result.AppendError ("no current frame"); - result.SetStatus (eReturnStatusFailed); } return result.Succeeded(); } |