| //===-- MICmdCmdData.cpp ----------------------------------------*- C++ -*-===// |
| // |
| // The LLVM Compiler Infrastructure |
| // |
| // This file is distributed under the University of Illinois Open Source |
| // License. See LICENSE.TXT for details. |
| // |
| //===----------------------------------------------------------------------===// |
| |
| //++ |
| // File: MICmdCmdData.cpp |
| // |
| // Overview: CMICmdCmdDataEvaluateExpression implementation. |
| // CMICmdCmdDataDisassemble implementation. |
| // CMICmdCmdDataReadMemoryBytes implementation. |
| // CMICmdCmdDataReadMemory implementation. |
| // CMICmdCmdDataListRegisterNames implementation. |
| // CMICmdCmdDataListRegisterValues implementation. |
| // CMICmdCmdDataListRegisterChanged implementation. |
| // CMICmdCmdDataWriteMemoryBytes implementation. |
| // CMICmdCmdDataWriteMemory implementation. |
| // |
| // Environment: Compilers: Visual C++ 12. |
| // gcc (Ubuntu/Linaro 4.8.1-10ubuntu9) 4.8.1 |
| // Libraries: See MIReadmetxt. |
| // |
| // Copyright: None. |
| //-- |
| |
| // Third Party Headers: |
| #include <lldb/API/SBThread.h> |
| #include <lldb/API/SBInstruction.h> |
| #include <lldb/API/SBInstructionList.h> |
| #include <lldb/API/SBStream.h> |
| |
| // In-house headers: |
| #include "MICmnConfig.h" |
| #include "MICmdCmdData.h" |
| #include "MICmnMIResultRecord.h" |
| #include "MICmnMIValueConst.h" |
| #include "MICmnLLDBDebugger.h" |
| #include "MICmnLLDBDebugSessionInfo.h" |
| #include "MICmnLLDBProxySBValue.h" |
| #include "MICmdArgContext.h" |
| #include "MICmdArgValNumber.h" |
| #include "MICmdArgValString.h" |
| #include "MICmdArgValThreadGrp.h" |
| #include "MICmdArgValOptionLong.h" |
| #include "MICmdArgValOptionShort.h" |
| #include "MICmdArgValListOfN.h" |
| #include "MICmdArgValConsume.h" |
| #include "MICmnLLDBDebugSessionInfoVarObj.h" |
| |
| //++ ------------------------------------------------------------------------------------ |
| // Details: CMICmdCmdDataEvaluateExpression constructor. |
| // Type: Method. |
| // Args: None. |
| // Return: None. |
| // Throws: None. |
| //-- |
| CMICmdCmdDataEvaluateExpression::CMICmdCmdDataEvaluateExpression( void ) |
| : m_bExpressionValid( true ) |
| , m_bEvaluatedExpression( true ) |
| , m_strValue( "??" ) |
| , m_bCompositeVarType( false ) |
| , m_constStrArgThread( "thread" ) |
| , m_constStrArgFrame( "frame" ) |
| , m_constStrArgExpr( "expr" ) |
| { |
| // Command factory matches this name with that received from the stdin stream |
| m_strMiCmd = "data-evaluate-expression"; |
| |
| // Required by the CMICmdFactory when registering *this command |
| m_pSelfCreatorFn = &CMICmdCmdDataEvaluateExpression::CreateSelf; |
| } |
| |
| //++ ------------------------------------------------------------------------------------ |
| // Details: CMICmdCmdDataEvaluateExpression destructor. |
| // Type: Overrideable. |
| // Args: None. |
| // Return: None. |
| // Throws: None. |
| //-- |
| CMICmdCmdDataEvaluateExpression::~CMICmdCmdDataEvaluateExpression( void ) |
| { |
| } |
| |
| //++ ------------------------------------------------------------------------------------ |
| // Details: The invoker requires this function. The parses the command line options |
| // arguments to extract values for each of those arguments. |
| // Type: Overridden. |
| // Args: None. |
| // Return: MIstatus::success - Functional succeeded. |
| // MIstatus::failure - Functional failed. |
| // Throws: None. |
| //-- |
| bool CMICmdCmdDataEvaluateExpression::ParseArgs( void ) |
| { |
| bool bOk = m_setCmdArgs.Add( *(new CMICmdArgValOptionLong( m_constStrArgThread, false, false, CMICmdArgValListBase::eArgValType_Number, 1 ) ) ); |
| bOk = bOk && m_setCmdArgs.Add( *(new CMICmdArgValOptionLong( m_constStrArgFrame, false, false, CMICmdArgValListBase::eArgValType_Number, 1 ) ) ); |
| bOk = bOk && m_setCmdArgs.Add( *(new CMICmdArgValString( m_constStrArgExpr, true, true, true, true ) ) ); |
| CMICmdArgContext argCntxt( m_cmdData.strMiCmdOption ); |
| if( bOk && !m_setCmdArgs.Validate( m_cmdData.strMiCmd, argCntxt ) ) |
| { |
| SetError( CMIUtilString::Format( MIRSRC( IDS_CMD_ERR_ARGS ), m_cmdData.strMiCmd.c_str(), m_setCmdArgs.GetErrorDescription().c_str() ) ); |
| return MIstatus::failure; |
| } |
| |
| return bOk; |
| } |
| |
| //++ ------------------------------------------------------------------------------------ |
| // Details: The invoker requires this function. The command does work in this function. |
| // The command is likely to communicate with the LLDB SBDebugger in here. |
| // Type: Overridden. |
| // Args: None. |
| // Return: MIstatus::success - Functional succeeded. |
| // MIstatus::failure - Functional failed. |
| // Throws: None. |
| //-- |
| bool CMICmdCmdDataEvaluateExpression::Execute( void ) |
| { |
| CMICMDBASE_GETOPTION( pArgExpr, String, m_constStrArgExpr ); |
| |
| const CMIUtilString & rExpression( pArgExpr->GetValue() ); |
| CMICmnLLDBDebugSessionInfo & rSessionInfo( CMICmnLLDBDebugSessionInfo::Instance() ); |
| lldb::SBProcess & rProcess = rSessionInfo.m_lldbProcess; |
| lldb::SBThread thread = rProcess.GetSelectedThread(); |
| m_bExpressionValid = (thread.GetNumFrames() > 0); |
| if( !m_bExpressionValid ) |
| return MIstatus::success; |
| |
| lldb::SBFrame frame = thread.GetSelectedFrame(); |
| lldb::SBValue value = frame.EvaluateExpression( rExpression.c_str() ); |
| if( !value.IsValid() ) |
| value = frame.FindVariable( rExpression.c_str() ); |
| if( !value.IsValid() ) |
| { |
| m_bEvaluatedExpression = false; |
| return MIstatus::success; |
| } |
| |
| MIuint64 nNumber = 0; |
| if( CMICmnLLDBProxySBValue::GetValueAsUnsigned( value, nNumber ) == MIstatus::success ) |
| { |
| const lldb::ValueType eValueType = value.GetValueType(); MIunused( eValueType ); |
| m_strValue = (value.GetValue() != nullptr) ? value.GetValue() : "??"; |
| |
| CMIUtilString strCString; |
| if( CMICmnLLDBProxySBValue::GetCString( value, strCString ) ) |
| { |
| m_strValue += CMIUtilString::Format( " '%s'", strCString.c_str() ); |
| } |
| return MIstatus::success; |
| } |
| |
| // Composite type i.e. struct |
| m_bCompositeVarType = true; |
| MIuint nChild = value.GetNumChildren(); |
| for( MIuint i = 0; i < nChild; i++ ) |
| { |
| lldb::SBValue member = value.GetChildAtIndex( i ); |
| const bool bValid = member.IsValid(); |
| CMIUtilString strType( MIRSRC( IDS_WORD_UNKNOWNTYPE_BRKTS ) ); |
| if( bValid ) |
| { |
| const CMIUtilString strValue( CMICmnLLDBDebugSessionInfoVarObj::GetValueStringFormatted( member, CMICmnLLDBDebugSessionInfoVarObj::eVarFormat_Natural ) ); |
| const char * pTypeName = member.GetName(); |
| if( pTypeName != nullptr ) |
| strType = pTypeName; |
| |
| // MI print "{variable = 1, variable2 = 3, variable3 = 5}" |
| const bool bNoQuotes = true; |
| const CMICmnMIValueConst miValueConst( strValue, bNoQuotes ); |
| const bool bUseSpaces = true; |
| const CMICmnMIValueResult miValueResult( strType, miValueConst, bUseSpaces ); |
| m_miValueTuple.Add( miValueResult, bUseSpaces ); |
| } |
| } |
| |
| return MIstatus::success; |
| } |
| |
| //++ ------------------------------------------------------------------------------------ |
| // Details: The invoker requires this function. The command prepares a MI Record Result |
| // for the work carried out in the Execute(). |
| // Type: Overridden. |
| // Args: None. |
| // Return: MIstatus::success - Functional succeeded. |
| // MIstatus::failure - Functional failed. |
| // Throws: None. |
| //-- |
| bool CMICmdCmdDataEvaluateExpression::Acknowledge( void ) |
| { |
| if( m_bExpressionValid ) |
| { |
| if( m_bEvaluatedExpression ) |
| { |
| if( m_bCompositeVarType ) |
| { |
| const CMICmnMIValueConst miValueConst( m_miValueTuple.GetString() ); |
| const CMICmnMIValueResult miValueResult( "value", miValueConst ); |
| const CMICmnMIResultRecord miRecordResult( m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Done, miValueResult ); |
| m_miResultRecord = miRecordResult; |
| return MIstatus::success; |
| } |
| |
| const CMICmnMIValueConst miValueConst( m_strValue ); |
| const CMICmnMIValueResult miValueResult( "value", miValueConst ); |
| const CMICmnMIResultRecord miRecordResult( m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Done, miValueResult ); |
| m_miResultRecord = miRecordResult; |
| return MIstatus::success; |
| } |
| |
| const CMICmnMIValueConst miValueConst( "could not evaluate expression" ); |
| const CMICmnMIValueResult miValueResult( "msg", miValueConst ); |
| const CMICmnMIResultRecord miRecordResult( m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Error, miValueResult ); |
| m_miResultRecord = miRecordResult; |
| return MIstatus::success; |
| } |
| |
| const CMICmnMIValueConst miValueConst( "invalid expression" ); |
| const CMICmnMIValueResult miValueResult( "msg", miValueConst ); |
| const CMICmnMIResultRecord miRecordResult( m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Error, miValueResult ); |
| m_miResultRecord = miRecordResult; |
| |
| return MIstatus::success; |
| } |
| |
| //++ ------------------------------------------------------------------------------------ |
| // Details: Required by the CMICmdFactory when registering *this command. The factory |
| // calls this function to create an instance of *this command. |
| // Type: Static method. |
| // Args: None. |
| // Return: CMICmdBase * - Pointer to a new command. |
| // Throws: None. |
| //-- |
| CMICmdBase * CMICmdCmdDataEvaluateExpression::CreateSelf( void ) |
| { |
| return new CMICmdCmdDataEvaluateExpression(); |
| } |
| |
| //--------------------------------------------------------------------------------------- |
| //--------------------------------------------------------------------------------------- |
| //--------------------------------------------------------------------------------------- |
| |
| //++ ------------------------------------------------------------------------------------ |
| // Details: CMICmdCmdDataDisassemble constructor. |
| // Type: Method. |
| // Args: None. |
| // Return: None. |
| // Throws: None. |
| //-- |
| CMICmdCmdDataDisassemble::CMICmdCmdDataDisassemble( void ) |
| : m_constStrArgThread( "thread" ) |
| , m_constStrArgAddrStart( "s" ) |
| , m_constStrArgAddrEnd( "e" ) |
| , m_constStrArgConsume( "--" ) |
| , m_constStrArgMode( "mode" ) |
| , m_miValueList( true ) |
| { |
| // Command factory matches this name with that received from the stdin stream |
| m_strMiCmd = "data-disassemble"; |
| |
| // Required by the CMICmdFactory when registering *this command |
| m_pSelfCreatorFn = &CMICmdCmdDataDisassemble::CreateSelf; |
| } |
| |
| //++ ------------------------------------------------------------------------------------ |
| // Details: CMICmdCmdDataDisassemble destructor. |
| // Type: Overrideable. |
| // Args: None. |
| // Return: None. |
| // Throws: None. |
| //-- |
| CMICmdCmdDataDisassemble::~CMICmdCmdDataDisassemble( void ) |
| { |
| } |
| |
| //++ ------------------------------------------------------------------------------------ |
| // Details: The invoker requires this function. The parses the command line options |
| // arguments to extract values for each of those arguments. |
| // Type: Overridden. |
| // Args: None. |
| // Return: MIstatus::success - Functional succeeded. |
| // MIstatus::failure - Functional failed. |
| // Throws: None. |
| //-- |
| bool CMICmdCmdDataDisassemble::ParseArgs( void ) |
| { |
| bool bOk = m_setCmdArgs.Add( *(new CMICmdArgValOptionLong( m_constStrArgThread, true, true, CMICmdArgValListBase::eArgValType_Number, 1 ) ) ); |
| bOk = bOk && m_setCmdArgs.Add( *(new CMICmdArgValOptionShort( m_constStrArgAddrStart, true, true, CMICmdArgValListBase::eArgValType_StringQuotedNumber, 1 ) ) ); |
| bOk = bOk && m_setCmdArgs.Add( *(new CMICmdArgValOptionShort( m_constStrArgAddrEnd, true, true, CMICmdArgValListBase::eArgValType_StringQuotedNumber, 1 ) ) ); |
| bOk = bOk && m_setCmdArgs.Add( *(new CMICmdArgValConsume( m_constStrArgConsume, true ) ) ); |
| bOk = bOk && m_setCmdArgs.Add( *(new CMICmdArgValNumber( m_constStrArgMode, true, true ) ) ); |
| CMICmdArgContext argCntxt( m_cmdData.strMiCmdOption ); |
| if( bOk && !m_setCmdArgs.Validate( m_cmdData.strMiCmd, argCntxt ) ) |
| { |
| SetError( CMIUtilString::Format( MIRSRC( IDS_CMD_ERR_ARGS ), m_cmdData.strMiCmd.c_str(), m_setCmdArgs.GetErrorDescription().c_str() ) ); |
| return MIstatus::failure; |
| } |
| |
| return bOk; |
| } |
| |
| //++ ------------------------------------------------------------------------------------ |
| // Details: The invoker requires this function. The command does work in this function. |
| // The command is likely to communicate with the LLDB SBDebugger in here. |
| // Type: Overridden. |
| // Args: None. |
| // Return: MIstatus::success - Functional succeeded. |
| // MIstatus::failure - Functional failed. |
| // Throws: None. |
| //-- |
| bool CMICmdCmdDataDisassemble::Execute( void ) |
| { |
| CMICMDBASE_GETOPTION( pArgThread, OptionLong, m_constStrArgThread ); |
| CMICMDBASE_GETOPTION( pArgAddrStart, OptionShort, m_constStrArgAddrStart ); |
| CMICMDBASE_GETOPTION( pArgAddrEnd, OptionShort, m_constStrArgAddrEnd ); |
| CMICMDBASE_GETOPTION( pArgMode, Number, m_constStrArgMode ); |
| |
| // Retrieve the --thread option's thread ID (only 1) |
| MIuint64 nThreadId = UINT64_MAX; |
| if( !pArgThread->GetExpectedOption< CMICmdArgValNumber, MIuint64 >( nThreadId ) ) |
| { |
| SetError( CMIUtilString::Format( MIRSRC( IDS_CMD_ERR_THREAD_INVALID ), m_cmdData.strMiCmd.c_str(), m_constStrArgThread.c_str() ) ); |
| return MIstatus::failure; |
| } |
| CMIUtilString strAddrStart; |
| if( !pArgAddrStart->GetExpectedOption< CMICmdArgValString, CMIUtilString >( strAddrStart ) ) |
| { |
| SetError( CMIUtilString::Format( MIRSRC( IDS_CMD_ERR_DISASM_ADDR_START_INVALID ), m_cmdData.strMiCmd.c_str(), m_constStrArgAddrStart.c_str() ) ); |
| return MIstatus::failure; |
| } |
| MIint64 nAddrStart = 0; |
| if( !strAddrStart.ExtractNumber( nAddrStart ) ) |
| { |
| SetError( CMIUtilString::Format( MIRSRC( IDS_CMD_ERR_DISASM_ADDR_START_INVALID ), m_cmdData.strMiCmd.c_str(), m_constStrArgAddrStart.c_str() ) ); |
| return MIstatus::failure; |
| } |
| |
| CMIUtilString strAddrEnd; |
| if( !pArgAddrEnd->GetExpectedOption< CMICmdArgValString, CMIUtilString >( strAddrEnd ) ) |
| { |
| SetError( CMIUtilString::Format( MIRSRC( IDS_CMD_ERR_DISASM_ADDR_END_INVALID ), m_cmdData.strMiCmd.c_str(), m_constStrArgAddrEnd.c_str() ) ); |
| return MIstatus::failure; |
| } |
| MIint64 nAddrEnd = 0; |
| if( !strAddrEnd.ExtractNumber( nAddrEnd ) ) |
| { |
| SetError( CMIUtilString::Format( MIRSRC( IDS_CMD_ERR_DISASM_ADDR_END_INVALID ), m_cmdData.strMiCmd.c_str(), m_constStrArgAddrEnd.c_str() ) ); |
| return MIstatus::failure; |
| } |
| const MIuint nDisasmMode = pArgMode->GetValue(); |
| |
| CMICmnLLDBDebugSessionInfo & rSessionInfo( CMICmnLLDBDebugSessionInfo::Instance() ); |
| lldb::SBTarget & rTarget = rSessionInfo.m_lldbTarget; |
| lldb::addr_t lldbStartAddr = static_cast< lldb::addr_t >( nAddrStart ); |
| lldb::SBInstructionList instructions = rTarget.ReadInstructions( lldb::SBAddress( lldbStartAddr, rTarget ), nAddrEnd - nAddrStart ); |
| const MIuint nInstructions = instructions.GetSize(); |
| for( size_t i = 0; i < nInstructions; i++ ) |
| { |
| const MIchar * pUnknown = "??"; |
| lldb::SBInstruction instrt = instructions.GetInstructionAtIndex( i ); |
| const MIchar * pStrMnemonic = instrt.GetMnemonic( rTarget ); |
| pStrMnemonic = (pStrMnemonic != nullptr) ? pStrMnemonic : pUnknown; |
| lldb::SBAddress address = instrt.GetAddress(); |
| lldb::addr_t addr = address.GetLoadAddress( rTarget ); |
| const MIchar * pFnName = address.GetFunction().GetName(); |
| pFnName = (pFnName != nullptr) ? pFnName : pUnknown; |
| lldb::addr_t addrOffSet = address.GetOffset(); |
| const MIchar * pStrOperands = instrt.GetOperands( rTarget ); |
| pStrOperands = (pStrOperands != nullptr) ? pStrOperands : pUnknown; |
| |
| // MI "{address=\"0x%08llx\",func-name=\"%s\",offset=\"%lld\",inst=\"%s %s\"}" |
| const CMICmnMIValueConst miValueConst( CMIUtilString::Format( "0x%08llx", addr ) ); |
| const CMICmnMIValueResult miValueResult( "address", miValueConst ); |
| CMICmnMIValueTuple miValueTuple( miValueResult ); |
| const CMICmnMIValueConst miValueConst2( pFnName ); |
| const CMICmnMIValueResult miValueResult2( "func-name", miValueConst2 ); |
| miValueTuple.Add( miValueResult2 ); |
| const CMICmnMIValueConst miValueConst3( CMIUtilString::Format( "0x%lld", addrOffSet ) ); |
| const CMICmnMIValueResult miValueResult3( "offset", miValueConst3 ); |
| miValueTuple.Add( miValueResult3 ); |
| const CMICmnMIValueConst miValueConst4( CMIUtilString::Format( "%s %s", pStrMnemonic, pStrOperands ) ); |
| const CMICmnMIValueResult miValueResult4( "inst", miValueConst4 ); |
| miValueTuple.Add( miValueResult4 ); |
| |
| if( nDisasmMode == 1 ) |
| { |
| lldb::SBLineEntry lineEntry = address.GetLineEntry(); |
| const MIuint nLine = lineEntry.GetLine(); |
| const MIchar * pFileName = lineEntry.GetFileSpec().GetFilename(); |
| pFileName = (pFileName != nullptr) ? pFileName : pUnknown; |
| |
| // MI "src_and_asm_line={line=\"%u\",file=\"%s\",line_asm_insn=[ ]}" |
| const CMICmnMIValueConst miValueConst( CMIUtilString::Format( "0x%u", nLine ) ); |
| const CMICmnMIValueResult miValueResult( "line", miValueConst ); |
| CMICmnMIValueTuple miValueTuple2( miValueResult ); |
| const CMICmnMIValueConst miValueConst2( pFileName ); |
| const CMICmnMIValueResult miValueResult2( "file", miValueConst2 ); |
| miValueTuple2.Add( miValueResult2 ); |
| const CMICmnMIValueList miValueList( miValueTuple ); |
| const CMICmnMIValueResult miValueResult3( "line_asm_insn", miValueList ); |
| miValueTuple2.Add( miValueResult3 ); |
| const CMICmnMIValueResult miValueResult4( "src_and_asm_line", miValueTuple2 ); |
| m_miValueList.Add( miValueResult4 ); |
| } |
| else |
| { |
| m_miValueList.Add( miValueTuple ); |
| } |
| } |
| |
| return MIstatus::success; |
| } |
| |
| //++ ------------------------------------------------------------------------------------ |
| // Details: The invoker requires this function. The command prepares a MI Record Result |
| // for the work carried out in the Execute(). |
| // Type: Overridden. |
| // Args: None. |
| // Return: MIstatus::success - Functional succeeded. |
| // MIstatus::failure - Functional failed. |
| // Throws: None. |
| //-- |
| bool CMICmdCmdDataDisassemble::Acknowledge( void ) |
| { |
| const CMICmnMIValueResult miValueResult( "asm_insns", m_miValueList ); |
| const CMICmnMIResultRecord miRecordResult( m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Done, miValueResult ); |
| m_miResultRecord = miRecordResult; |
| |
| return MIstatus::success; |
| } |
| |
| //++ ------------------------------------------------------------------------------------ |
| // Details: Required by the CMICmdFactory when registering *this command. The factory |
| // calls this function to create an instance of *this command. |
| // Type: Static method. |
| // Args: None. |
| // Return: CMICmdBase * - Pointer to a new command. |
| // Throws: None. |
| //-- |
| CMICmdBase * CMICmdCmdDataDisassemble::CreateSelf( void ) |
| { |
| return new CMICmdCmdDataDisassemble(); |
| } |
| |
| //--------------------------------------------------------------------------------------- |
| //--------------------------------------------------------------------------------------- |
| //--------------------------------------------------------------------------------------- |
| |
| //++ ------------------------------------------------------------------------------------ |
| // Details: CMICmdCmdDataReadMemoryBytes constructor. |
| // Type: Method. |
| // Args: None. |
| // Return: None. |
| // Throws: None. |
| //-- |
| CMICmdCmdDataReadMemoryBytes::CMICmdCmdDataReadMemoryBytes( void ) |
| : m_constStrArgThread( "thread" ) |
| , m_constStrArgByteOffset( "o" ) |
| , m_constStrArgAddrStart( "address" ) |
| , m_constStrArgNumBytes( "count" ) |
| , m_pBufferMemory( nullptr ) |
| , m_nAddrStart( 0 ) |
| , m_nAddrNumBytesToRead( 0 ) |
| , m_nAddrOffset( 0 ) |
| { |
| // Command factory matches this name with that received from the stdin stream |
| m_strMiCmd = "data-read-memory-bytes"; |
| |
| // Required by the CMICmdFactory when registering *this command |
| m_pSelfCreatorFn = &CMICmdCmdDataReadMemoryBytes::CreateSelf; |
| } |
| |
| //++ ------------------------------------------------------------------------------------ |
| // Details: CMICmdCmdDataReadMemoryBytes destructor. |
| // Type: Overrideable. |
| // Args: None. |
| // Return: None. |
| // Throws: None. |
| //-- |
| CMICmdCmdDataReadMemoryBytes::~CMICmdCmdDataReadMemoryBytes( void ) |
| { |
| if( m_pBufferMemory != nullptr ) |
| { |
| delete [] m_pBufferMemory; |
| m_pBufferMemory = nullptr; |
| } |
| } |
| |
| //++ ------------------------------------------------------------------------------------ |
| // Details: The invoker requires this function. The parses the command line options |
| // arguments to extract values for each of those arguments. |
| // Type: Overridden. |
| // Args: None. |
| // Return: MIstatus::success - Functional succeeded. |
| // MIstatus::failure - Functional failed. |
| // Throws: None. |
| //-- |
| bool CMICmdCmdDataReadMemoryBytes::ParseArgs( void ) |
| { |
| bool bOk = m_setCmdArgs.Add( *(new CMICmdArgValOptionLong( m_constStrArgThread, false, false, CMICmdArgValListBase::eArgValType_Number, 1 ) ) ); |
| bOk = bOk && m_setCmdArgs.Add( *(new CMICmdArgValOptionShort( m_constStrArgByteOffset, false, true, CMICmdArgValListBase::eArgValType_Number, 1 ) ) ); |
| bOk = bOk && m_setCmdArgs.Add( *(new CMICmdArgValNumber( m_constStrArgAddrStart, true, true ) ) ); |
| bOk = bOk && m_setCmdArgs.Add( *(new CMICmdArgValNumber( m_constStrArgNumBytes, true, true ) ) ); |
| CMICmdArgContext argCntxt( m_cmdData.strMiCmdOption ); |
| if( bOk && !m_setCmdArgs.Validate( m_cmdData.strMiCmd, argCntxt ) ) |
| { |
| SetError( CMIUtilString::Format( MIRSRC( IDS_CMD_ERR_ARGS ), m_cmdData.strMiCmd.c_str(), m_setCmdArgs.GetErrorDescription().c_str() ) ); |
| return MIstatus::failure; |
| } |
| |
| return bOk; |
| } |
| |
| //++ ------------------------------------------------------------------------------------ |
| // Details: The invoker requires this function. The command does work in this function. |
| // The command is likely to communicate with the LLDB SBDebugger in here. |
| // Type: Overridden. |
| // Args: None. |
| // Return: MIstatus::success - Functional succeeded. |
| // MIstatus::failure - Functional failed. |
| // Throws: None. |
| //-- |
| bool CMICmdCmdDataReadMemoryBytes::Execute( void ) |
| { |
| CMICMDBASE_GETOPTION( pArgAddrStart, Number, m_constStrArgAddrStart ); |
| CMICMDBASE_GETOPTION( pArgAddrOffset, Number, m_constStrArgByteOffset ); |
| CMICMDBASE_GETOPTION( pArgNumBytes, Number, m_constStrArgNumBytes ); |
| |
| const MIuint64 nAddrStart = pArgAddrStart->GetValue(); |
| const MIuint64 nAddrNumBytes = pArgNumBytes->GetValue(); |
| if( pArgAddrOffset->GetFound() ) |
| m_nAddrOffset = pArgAddrOffset->GetValue(); |
| |
| m_pBufferMemory = new MIuchar[ nAddrNumBytes ]; |
| if( m_pBufferMemory == nullptr ) |
| { |
| SetError( CMIUtilString::Format( MIRSRC( IDS_CMD_ERR_MEMORY_ALLOC_FAILURE ), m_cmdData.strMiCmd.c_str(), nAddrNumBytes ) ); |
| return MIstatus::failure; |
| } |
| |
| CMICmnLLDBDebugSessionInfo & rSessionInfo( CMICmnLLDBDebugSessionInfo::Instance() ); |
| lldb::SBProcess & rProcess = rSessionInfo.m_lldbProcess; |
| lldb::SBError error; |
| const MIuint64 nReadBytes = rProcess.ReadMemory( static_cast< lldb::addr_t >( nAddrStart ), (void *) m_pBufferMemory, nAddrNumBytes, error ); |
| if( nReadBytes != nAddrNumBytes ) |
| { |
| SetError( CMIUtilString::Format( MIRSRC( IDS_CMD_ERR_LLDB_ERR_NOT_READ_WHOLE_BLK ), m_cmdData.strMiCmd.c_str(), nAddrNumBytes, nAddrStart ) ); |
| return MIstatus::failure; |
| } |
| if( error.Fail() ) |
| { |
| lldb::SBStream err; |
| const bool bOk = error.GetDescription( err ); MIunused( bOk ); |
| SetError( CMIUtilString::Format( MIRSRC( IDS_CMD_ERR_LLDB_ERR_READ_MEM_BYTES ), m_cmdData.strMiCmd.c_str(), nAddrNumBytes, nAddrStart, err.GetData() ) ); |
| return MIstatus::failure; |
| } |
| |
| m_nAddrStart = nAddrStart; |
| m_nAddrNumBytesToRead = nAddrNumBytes; |
| |
| return MIstatus::success; |
| } |
| |
| //++ ------------------------------------------------------------------------------------ |
| // Details: The invoker requires this function. The command prepares a MI Record Result |
| // for the work carried out in the Execute(). |
| // Type: Overridden. |
| // Args: None. |
| // Return: MIstatus::success - Functional succeeded. |
| // MIstatus::failure - Functional failed. |
| // Throws: None. |
| //-- |
| bool CMICmdCmdDataReadMemoryBytes::Acknowledge( void ) |
| { |
| // MI: memory=[{begin=\"0x%08x\",offset=\"0x%08x\",end=\"0x%08x\",contents=\" \" }]" |
| const CMICmnMIValueConst miValueConst( CMIUtilString::Format( "0x%08x", m_nAddrStart ) ); |
| const CMICmnMIValueResult miValueResult( "begin", miValueConst ); |
| CMICmnMIValueTuple miValueTuple( miValueResult ); |
| const CMICmnMIValueConst miValueConst2( CMIUtilString::Format( "0x%08x", m_nAddrOffset ) ); |
| const CMICmnMIValueResult miValueResult2( "offset", miValueConst2 ); |
| miValueTuple.Add( miValueResult2 ); |
| const CMICmnMIValueConst miValueConst3( CMIUtilString::Format( "0x%08x", m_nAddrStart + m_nAddrNumBytesToRead ) ); |
| const CMICmnMIValueResult miValueResult3( "end", miValueConst3 ); |
| miValueTuple.Add( miValueResult3 ); |
| |
| // MI: contents=\" \" |
| CMIUtilString strContent; |
| strContent.reserve( (m_nAddrNumBytesToRead << 1) + 1 ); |
| for( MIuint64 i = 0; i < m_nAddrNumBytesToRead; i ++ ) |
| { |
| strContent += CMIUtilString::Format( "%02x", m_pBufferMemory[ i ] ); |
| } |
| const CMICmnMIValueConst miValueConst4( strContent ); |
| const CMICmnMIValueResult miValueResult4( "contents", miValueConst4 ); |
| miValueTuple.Add( miValueResult4 ); |
| const CMICmnMIValueList miValueList( miValueTuple ); |
| const CMICmnMIValueResult miValueResult5( "memory", miValueList ); |
| |
| const CMICmnMIResultRecord miRecordResult( m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Done, miValueResult5 ); |
| m_miResultRecord = miRecordResult; |
| |
| return MIstatus::success; |
| } |
| |
| //++ ------------------------------------------------------------------------------------ |
| // Details: Required by the CMICmdFactory when registering *this command. The factory |
| // calls this function to create an instance of *this command. |
| // Type: Static method. |
| // Args: None. |
| // Return: CMICmdBase * - Pointer to a new command. |
| // Throws: None. |
| //-- |
| CMICmdBase * CMICmdCmdDataReadMemoryBytes::CreateSelf( void ) |
| { |
| return new CMICmdCmdDataReadMemoryBytes(); |
| } |
| |
| //--------------------------------------------------------------------------------------- |
| //--------------------------------------------------------------------------------------- |
| //--------------------------------------------------------------------------------------- |
| |
| //++ ------------------------------------------------------------------------------------ |
| // Details: CMICmdCmdDataReadMemory constructor. |
| // Type: Method. |
| // Args: None. |
| // Return: None. |
| // Throws: None. |
| //-- |
| CMICmdCmdDataReadMemory::CMICmdCmdDataReadMemory( void ) |
| { |
| // Command factory matches this name with that received from the stdin stream |
| m_strMiCmd = "data-read-memory"; |
| |
| // Required by the CMICmdFactory when registering *this command |
| m_pSelfCreatorFn = &CMICmdCmdDataReadMemory::CreateSelf; |
| } |
| |
| //++ ------------------------------------------------------------------------------------ |
| // Details: CMICmdCmdDataReadMemory destructor. |
| // Type: Overrideable. |
| // Args: None. |
| // Return: None. |
| // Throws: None. |
| //-- |
| CMICmdCmdDataReadMemory::~CMICmdCmdDataReadMemory( void ) |
| { |
| } |
| |
| //++ ------------------------------------------------------------------------------------ |
| // Details: The invoker requires this function. The command does work in this function. |
| // The command is likely to communicate with the LLDB SBDebugger in here. |
| // Type: Overridden. |
| // Args: None. |
| // Return: MIstatus::success - Functional succeeded. |
| // MIstatus::failure - Functional failed. |
| // Throws: None. |
| //-- |
| bool CMICmdCmdDataReadMemory::Execute( void ) |
| { |
| // Do nothing - command deprecated use "data-read-memory-bytes" command |
| return MIstatus::success; |
| } |
| |
| //++ ------------------------------------------------------------------------------------ |
| // Details: The invoker requires this function. The command prepares a MI Record Result |
| // for the work carried out in the Execute(). |
| // Type: Overridden. |
| // Args: None. |
| // Return: MIstatus::success - Functional succeeded. |
| // MIstatus::failure - Functional failed. |
| // Throws: None. |
| //-- |
| bool CMICmdCmdDataReadMemory::Acknowledge( void ) |
| { |
| // Command CMICmdCmdSupportListFeatures sends "data-read-memory-bytes" which causes this command not to be called |
| const CMICmnMIValueConst miValueConst( MIRSRC( IDS_CMD_ERR_NOT_IMPLEMENTED_DEPRECATED ) ); |
| const CMICmnMIValueResult miValueResult( "msg", miValueConst ); |
| const CMICmnMIResultRecord miRecordResult( m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Error, miValueResult ); |
| m_miResultRecord = miRecordResult; |
| |
| return MIstatus::success; |
| } |
| |
| //++ ------------------------------------------------------------------------------------ |
| // Details: Required by the CMICmdFactory when registering *this command. The factory |
| // calls this function to create an instance of *this command. |
| // Type: Static method. |
| // Args: None. |
| // Return: CMICmdBase * - Pointer to a new command. |
| // Throws: None. |
| //-- |
| CMICmdBase * CMICmdCmdDataReadMemory::CreateSelf( void ) |
| { |
| return new CMICmdCmdDataReadMemory(); |
| } |
| |
| //--------------------------------------------------------------------------------------- |
| //--------------------------------------------------------------------------------------- |
| //--------------------------------------------------------------------------------------- |
| |
| //++ ------------------------------------------------------------------------------------ |
| // Details: CMICmdCmdDataListRegisterNames constructor. |
| // Type: Method. |
| // Args: None. |
| // Return: None. |
| // Throws: None. |
| //-- |
| CMICmdCmdDataListRegisterNames::CMICmdCmdDataListRegisterNames( void ) |
| : m_constStrArgThreadGroup( "thread-group" ) |
| , m_constStrArgRegNo( "regno" ) |
| , m_miValueList( true ) |
| { |
| // Command factory matches this name with that received from the stdin stream |
| m_strMiCmd = "data-list-register-names"; |
| |
| // Required by the CMICmdFactory when registering *this command |
| m_pSelfCreatorFn = &CMICmdCmdDataListRegisterNames::CreateSelf; |
| } |
| |
| //++ ------------------------------------------------------------------------------------ |
| // Details: CMICmdCmdDataReadMemoryBytes destructor. |
| // Type: Overrideable. |
| // Args: None. |
| // Return: None. |
| // Throws: None. |
| //-- |
| CMICmdCmdDataListRegisterNames::~CMICmdCmdDataListRegisterNames( void ) |
| { |
| } |
| |
| //++ ------------------------------------------------------------------------------------ |
| // Details: The invoker requires this function. The parses the command line options |
| // arguments to extract values for each of those arguments. |
| // Type: Overridden. |
| // Args: None. |
| // Return: MIstatus::success - Functional succeeded. |
| // MIstatus::failure - Functional failed. |
| // Throws: None. |
| //-- |
| bool CMICmdCmdDataListRegisterNames::ParseArgs( void ) |
| { |
| bool bOk = m_setCmdArgs.Add( *(new CMICmdArgValOptionLong( m_constStrArgThreadGroup, false, false, CMICmdArgValListBase::eArgValType_ThreadGrp, 1 ) ) ); |
| bOk = bOk && m_setCmdArgs.Add( *(new CMICmdArgValListOfN( m_constStrArgRegNo, false, false, CMICmdArgValListBase::eArgValType_Number ) ) ); |
| CMICmdArgContext argCntxt( m_cmdData.strMiCmdOption ); |
| if( bOk && !m_setCmdArgs.Validate( m_cmdData.strMiCmd, argCntxt ) ) |
| { |
| SetError( CMIUtilString::Format( MIRSRC( IDS_CMD_ERR_ARGS ), m_cmdData.strMiCmd.c_str(), m_setCmdArgs.GetErrorDescription().c_str() ) ); |
| return MIstatus::failure; |
| } |
| |
| return bOk; |
| } |
| |
| //++ ------------------------------------------------------------------------------------ |
| // Details: The invoker requires this function. The command does work in this function. |
| // The command is likely to communicate with the LLDB SBDebugger in here. |
| // Type: Overridden. |
| // Args: None. |
| // Return: MIstatus::success - Functional succeeded. |
| // MIstatus::failure - Functional failed. |
| // Throws: None. |
| //-- |
| bool CMICmdCmdDataListRegisterNames::Execute( void ) |
| { |
| CMICmnLLDBDebugSessionInfo & rSessionInfo( CMICmnLLDBDebugSessionInfo::Instance() ); |
| lldb::SBProcess & rProcess = rSessionInfo.m_lldbProcess; |
| if( !rProcess.IsValid() ) |
| { |
| SetError( CMIUtilString::Format( MIRSRC( IDS_CMD_ERR_INVALID_PROCESS ), m_cmdData.strMiCmd.c_str() ) ); |
| return MIstatus::failure; |
| } |
| |
| lldb::SBThread thread = rProcess.GetSelectedThread(); |
| lldb::SBFrame frame = thread.GetSelectedFrame(); |
| lldb::SBValueList registers = frame.GetRegisters(); |
| const MIuint nRegisters = registers.GetSize(); |
| for( MIuint i = 0; i < nRegisters; i++ ) |
| { |
| lldb::SBValue value = registers.GetValueAtIndex( i ); |
| const MIchar * pRegName = value.GetName(); |
| const MIchar * pUnknown = "??"; |
| pRegName = (pRegName != nullptr) ? pRegName : pUnknown; |
| const MIuint nRegChildren = value.GetNumChildren(); |
| for( MIuint j = 0; j < nRegChildren; j++ ) |
| { |
| lldb::SBValue value2 = value.GetChildAtIndex( j ); |
| if( value2.IsValid() ) |
| { |
| const MIchar * pRegName = value2.GetName(); |
| pRegName = (pRegName != nullptr) ? pRegName : pUnknown; |
| const CMICmnMIValueConst miValueConst( pRegName ); |
| m_miValueList.Add( miValueConst ); |
| } |
| } |
| } |
| |
| return MIstatus::success; |
| } |
| |
| //++ ------------------------------------------------------------------------------------ |
| // Details: The invoker requires this function. The command prepares a MI Record Result |
| // for the work carried out in the Execute(). |
| // Type: Overridden. |
| // Args: None. |
| // Return: MIstatus::success - Functional succeeded. |
| // MIstatus::failure - Functional failed. |
| // Throws: None. |
| //-- |
| bool CMICmdCmdDataListRegisterNames::Acknowledge( void ) |
| { |
| const CMICmnMIValueResult miValueResult( "register-names", m_miValueList ); |
| const CMICmnMIResultRecord miRecordResult( m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Done, miValueResult ); |
| m_miResultRecord = miRecordResult; |
| |
| return MIstatus::success; |
| } |
| |
| //++ ------------------------------------------------------------------------------------ |
| // Details: Required by the CMICmdFactory when registering *this command. The factory |
| // calls this function to create an instance of *this command. |
| // Type: Static method. |
| // Args: None. |
| // Return: CMICmdBase * - Pointer to a new command. |
| // Throws: None. |
| //-- |
| CMICmdBase * CMICmdCmdDataListRegisterNames::CreateSelf( void ) |
| { |
| return new CMICmdCmdDataListRegisterNames(); |
| } |
| |
| //--------------------------------------------------------------------------------------- |
| //--------------------------------------------------------------------------------------- |
| //--------------------------------------------------------------------------------------- |
| |
| //++ ------------------------------------------------------------------------------------ |
| // Details: CMICmdCmdDataListRegisterValues constructor. |
| // Type: Method. |
| // Args: None. |
| // Return: None. |
| // Throws: None. |
| //-- |
| CMICmdCmdDataListRegisterValues::CMICmdCmdDataListRegisterValues( void ) |
| : m_constStrArgThread( "thread" ) |
| , m_constStrArgSkip( "skip-unavailable" ) |
| , m_constStrArgFormat( "fmt" ) |
| , m_constStrArgRegNo( "regno" ) |
| , m_miValueList( true ) |
| , m_pProcess( nullptr ) |
| { |
| // Command factory matches this name with that received from the stdin stream |
| m_strMiCmd = "data-list-register-values"; |
| |
| // Required by the CMICmdFactory when registering *this command |
| m_pSelfCreatorFn = &CMICmdCmdDataListRegisterValues::CreateSelf; |
| } |
| |
| //++ ------------------------------------------------------------------------------------ |
| // Details: CMICmdCmdDataListRegisterValues destructor. |
| // Type: Overrideable. |
| // Args: None. |
| // Return: None. |
| // Throws: None. |
| //-- |
| CMICmdCmdDataListRegisterValues::~CMICmdCmdDataListRegisterValues( void ) |
| { |
| } |
| |
| //++ ------------------------------------------------------------------------------------ |
| // Details: The invoker requires this function. The parses the command line options |
| // arguments to extract values for each of those arguments. |
| // Type: Overridden. |
| // Args: None. |
| // Return: MIstatus::success - Functional succeeded. |
| // MIstatus::failure - Functional failed. |
| // Throws: None. |
| //-- |
| bool CMICmdCmdDataListRegisterValues::ParseArgs( void ) |
| { |
| bool bOk = m_setCmdArgs.Add( *(new CMICmdArgValOptionLong( m_constStrArgThread, false, false, CMICmdArgValListBase::eArgValType_Number, 1 ) ) ); |
| bOk = bOk && m_setCmdArgs.Add( *(new CMICmdArgValOptionLong( m_constStrArgSkip, false, false ) ) ); |
| bOk = bOk && m_setCmdArgs.Add( *(new CMICmdArgValString( m_constStrArgFormat, true, true ) ) ); |
| bOk = bOk && m_setCmdArgs.Add( *(new CMICmdArgValListOfN( m_constStrArgRegNo, false, true, CMICmdArgValListBase::eArgValType_Number ) ) ); |
| CMICmdArgContext argCntxt( m_cmdData.strMiCmdOption ); |
| if( bOk && !m_setCmdArgs.Validate( m_cmdData.strMiCmd, argCntxt ) ) |
| { |
| SetError( CMIUtilString::Format( MIRSRC( IDS_CMD_ERR_ARGS ), m_cmdData.strMiCmd.c_str(), m_setCmdArgs.GetErrorDescription().c_str() ) ); |
| return MIstatus::failure; |
| } |
| |
| return bOk; |
| } |
| |
| //++ ------------------------------------------------------------------------------------ |
| // Details: The invoker requires this function. The command does work in this function. |
| // The command is likely to communicate with the LLDB SBDebugger in here. |
| // Type: Overridden. |
| // Args: None. |
| // Return: MIstatus::success - Functional succeeded. |
| // MIstatus::failure - Functional failed. |
| // Throws: None. |
| //-- |
| bool CMICmdCmdDataListRegisterValues::Execute( void ) |
| { |
| CMICMDBASE_GETOPTION( pArgFormat, String, m_constStrArgFormat ); |
| CMICMDBASE_GETOPTION( pArgRegNo, ListOfN, m_constStrArgRegNo ); |
| |
| const CMIUtilString & rStrFormat( pArgFormat->GetValue() ); |
| if( rStrFormat.length() != 1 ) |
| { |
| SetError( CMIUtilString::Format( MIRSRC( IDS_CMD_ERR_INVALID_FORMAT_TYPE ), m_cmdData.strMiCmd.c_str(), rStrFormat.c_str() ) ); |
| return MIstatus::failure; |
| } |
| const CMICmnLLDBDebugSessionInfoVarObj::varFormat_e eFormat = CMICmnLLDBDebugSessionInfoVarObj::GetVarFormatForChar( rStrFormat[ 0 ] ); |
| if( eFormat == CMICmnLLDBDebugSessionInfoVarObj::eVarFormat_Invalid ) |
| { |
| SetError( CMIUtilString::Format( MIRSRC( IDS_CMD_ERR_INVALID_FORMAT_TYPE ), m_cmdData.strMiCmd.c_str(), rStrFormat.c_str() ) ); |
| return MIstatus::failure; |
| } |
| |
| CMICmnLLDBDebugSessionInfo & rSessionInfo( CMICmnLLDBDebugSessionInfo::Instance() ); |
| lldb::SBProcess & rProcess = rSessionInfo.m_lldbProcess; |
| if( !rProcess.IsValid() ) |
| { |
| SetError( CMIUtilString::Format( MIRSRC( IDS_CMD_ERR_INVALID_PROCESS ), m_cmdData.strMiCmd.c_str() ) ); |
| return MIstatus::failure; |
| } |
| m_pProcess = &rProcess; |
| |
| const CMICmdArgValListBase::VecArgObjPtr_t & rVecRegNo( pArgRegNo->GetExpectedOptions() ); |
| CMICmdArgValListBase::VecArgObjPtr_t::const_iterator it = rVecRegNo.begin(); |
| while( it != rVecRegNo.end() ) |
| { |
| const CMICmdArgValNumber * pRegNo = static_cast< CMICmdArgValNumber * >( *it ); |
| const MIuint nReg = pRegNo->GetValue(); |
| lldb::SBValue regValue = GetRegister( nReg ); |
| const CMIUtilString strRegValue( CMICmnLLDBDebugSessionInfoVarObj::GetValueStringFormatted( regValue, eFormat ) ); |
| |
| const CMICmnMIValueConst miValueConst( CMIUtilString::Format( "%u", nReg ) ); |
| const CMICmnMIValueResult miValueResult( "number", miValueConst ); |
| CMICmnMIValueTuple miValueTuple( miValueResult ); |
| const CMICmnMIValueConst miValueConst2( strRegValue ); |
| const CMICmnMIValueResult miValueResult2( "value", miValueConst2 ); |
| miValueTuple.Add( miValueResult2 ); |
| m_miValueList.Add( miValueTuple ); |
| |
| // Next |
| ++it; |
| } |
| |
| return MIstatus::success; |
| } |
| |
| //++ ------------------------------------------------------------------------------------ |
| // Details: The invoker requires this function. The command prepares a MI Record Result |
| // for the work carried out in the Execute(). |
| // Type: Overridden. |
| // Args: None. |
| // Return: MIstatus::success - Functional succeeded. |
| // MIstatus::failure - Functional failed. |
| // Throws: None. |
| //-- |
| bool CMICmdCmdDataListRegisterValues::Acknowledge( void ) |
| { |
| const CMICmnMIValueResult miValueResult( "register-values", m_miValueList ); |
| const CMICmnMIResultRecord miRecordResult( m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Done, miValueResult ); |
| m_miResultRecord = miRecordResult; |
| |
| return MIstatus::success; |
| } |
| |
| //++ ------------------------------------------------------------------------------------ |
| // Details: Required by the CMICmdFactory when registering *this command. The factory |
| // calls this function to create an instance of *this command. |
| // Type: Static method. |
| // Args: None. |
| // Return: CMICmdBase * - Pointer to a new command. |
| // Throws: None. |
| //-- |
| CMICmdBase * CMICmdCmdDataListRegisterValues::CreateSelf( void ) |
| { |
| return new CMICmdCmdDataListRegisterValues(); |
| } |
| |
| //++ ------------------------------------------------------------------------------------ |
| // Details: Required by the CMICmdFactory when registering *this command. The factory |
| // calls this function to create an instance of *this command. |
| // Type: Method. |
| // Args: None. |
| // Return: lldb::SBValue - LLDB SBValue object. |
| // Throws: None. |
| //-- |
| lldb::SBValue CMICmdCmdDataListRegisterValues::GetRegister( const MIuint vRegisterIndex ) const |
| { |
| lldb::SBThread thread = m_pProcess->GetSelectedThread(); |
| lldb::SBFrame frame = thread.GetSelectedFrame(); |
| lldb::SBValueList registers = frame.GetRegisters(); |
| const MIuint nRegisters = registers.GetSize(); |
| for( MIuint i = 0; i < nRegisters; i++ ) |
| { |
| lldb::SBValue value = registers.GetValueAtIndex( i ); |
| const MIuint nRegChildren = value.GetNumChildren(); |
| if( nRegChildren > 0 ) |
| { |
| lldb::SBValue value2 = value.GetChildAtIndex( vRegisterIndex ); |
| if( value2.IsValid() ) |
| { |
| return value2; |
| } |
| } |
| } |
| |
| return lldb::SBValue(); |
| } |
| |
| //--------------------------------------------------------------------------------------- |
| //--------------------------------------------------------------------------------------- |
| //--------------------------------------------------------------------------------------- |
| |
| //++ ------------------------------------------------------------------------------------ |
| // Details: CMICmdCmdDataListRegisterChanged constructor. |
| // Type: Method. |
| // Args: None. |
| // Return: None. |
| // Throws: None. |
| //-- |
| CMICmdCmdDataListRegisterChanged::CMICmdCmdDataListRegisterChanged( void ) |
| { |
| // Command factory matches this name with that received from the stdin stream |
| m_strMiCmd = "data-list-changed-registers"; |
| |
| // Required by the CMICmdFactory when registering *this command |
| m_pSelfCreatorFn = &CMICmdCmdDataListRegisterChanged::CreateSelf; |
| } |
| |
| //++ ------------------------------------------------------------------------------------ |
| // Details: CMICmdCmdDataListRegisterChanged destructor. |
| // Type: Overrideable. |
| // Args: None. |
| // Return: None. |
| // Throws: None. |
| //-- |
| CMICmdCmdDataListRegisterChanged::~CMICmdCmdDataListRegisterChanged( void ) |
| { |
| } |
| |
| //++ ------------------------------------------------------------------------------------ |
| // Details: The invoker requires this function. The command does work in this function. |
| // The command is likely to communicate with the LLDB SBDebugger in here. |
| // Type: Overridden. |
| // Args: None. |
| // Return: MIstatus::success - Functional succeeded. |
| // MIstatus::failure - Functional failed. |
| // Throws: None. |
| //-- |
| bool CMICmdCmdDataListRegisterChanged::Execute( void ) |
| { |
| // Do nothing |
| |
| return MIstatus::success; |
| } |
| |
| //++ ------------------------------------------------------------------------------------ |
| // Details: The invoker requires this function. The command prepares a MI Record Result |
| // for the work carried out in the Execute(). |
| // Type: Overridden. |
| // Args: None. |
| // Return: MIstatus::success - Functional succeeded. |
| // MIstatus::failure - Functional failed. |
| // Throws: None. |
| //-- |
| bool CMICmdCmdDataListRegisterChanged::Acknowledge( void ) |
| { |
| const CMICmnMIValueConst miValueConst( MIRSRC( IDS_WORD_NOT_IMPLEMENTED ) ); |
| const CMICmnMIValueResult miValueResult( "msg", miValueConst ); |
| const CMICmnMIResultRecord miRecordResult( m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Error, miValueResult ); |
| m_miResultRecord = miRecordResult; |
| |
| return MIstatus::success; |
| } |
| |
| //++ ------------------------------------------------------------------------------------ |
| // Details: Required by the CMICmdFactory when registering *this command. The factory |
| // calls this function to create an instance of *this command. |
| // Type: Static method. |
| // Args: None. |
| // Return: CMICmdBase * - Pointer to a new command. |
| // Throws: None. |
| //-- |
| CMICmdBase * CMICmdCmdDataListRegisterChanged::CreateSelf( void ) |
| { |
| return new CMICmdCmdDataListRegisterChanged(); |
| } |
| |
| //--------------------------------------------------------------------------------------- |
| //--------------------------------------------------------------------------------------- |
| //--------------------------------------------------------------------------------------- |
| |
| //++ ------------------------------------------------------------------------------------ |
| // Details: CMICmdCmdDataWriteMemoryBytes constructor. |
| // Type: Method. |
| // Args: None. |
| // Return: None. |
| // Throws: None. |
| //-- |
| CMICmdCmdDataWriteMemoryBytes::CMICmdCmdDataWriteMemoryBytes( void ) |
| : m_constStrArgThread( "thread" ) |
| , m_constStrArgAddr( "address" ) |
| , m_constStrArgContents( "contents" ) |
| , m_constStrArgCount( "count" ) |
| , m_nAddr( 0 ) |
| , m_nCount( 0 ) |
| { |
| // Command factory matches this name with that received from the stdin stream |
| m_strMiCmd = "data-write-memory-bytes"; |
| |
| // Required by the CMICmdFactory when registering *this command |
| m_pSelfCreatorFn = &CMICmdCmdDataWriteMemoryBytes::CreateSelf; |
| } |
| |
| //++ ------------------------------------------------------------------------------------ |
| // Details: CMICmdCmdDataWriteMemoryBytes destructor. |
| // Type: Overrideable. |
| // Args: None. |
| // Return: None. |
| // Throws: None. |
| //-- |
| CMICmdCmdDataWriteMemoryBytes::~CMICmdCmdDataWriteMemoryBytes( void ) |
| { |
| } |
| |
| //++ ------------------------------------------------------------------------------------ |
| // Details: The invoker requires this function. The parses the command line options |
| // arguments to extract values for each of those arguments. |
| // Type: Overridden. |
| // Args: None. |
| // Return: MIstatus::success - Functional succeeded. |
| // MIstatus::failure - Functional failed. |
| // Throws: None. |
| //-- |
| bool CMICmdCmdDataWriteMemoryBytes::ParseArgs( void ) |
| { |
| bool bOk = m_setCmdArgs.Add( *(new CMICmdArgValOptionLong( m_constStrArgThread, false, false, CMICmdArgValListBase::eArgValType_Number, 1 ) ) ); |
| bOk = bOk && m_setCmdArgs.Add( *(new CMICmdArgValString( m_constStrArgAddr, true, true, false, true ) ) ); |
| bOk = bOk && m_setCmdArgs.Add( *(new CMICmdArgValString( m_constStrArgContents, true, true, true, true ) ) ); |
| bOk = bOk && m_setCmdArgs.Add( *(new CMICmdArgValString( m_constStrArgCount, false, true, false, true ) ) ); |
| CMICmdArgContext argCntxt( m_cmdData.strMiCmdOption ); |
| if( bOk && !m_setCmdArgs.Validate( m_cmdData.strMiCmd, argCntxt ) ) |
| { |
| SetError( CMIUtilString::Format( MIRSRC( IDS_CMD_ERR_ARGS ), m_cmdData.strMiCmd.c_str(), m_setCmdArgs.GetErrorDescription().c_str() ) ); |
| return MIstatus::failure; |
| } |
| |
| return bOk; |
| } |
| |
| //++ ------------------------------------------------------------------------------------ |
| // Details: The invoker requires this function. The command does work in this function. |
| // The command is likely to communicate with the LLDB SBDebugger in here. |
| // Type: Overridden. |
| // Args: None. |
| // Return: MIstatus::success - Functional succeeded. |
| // MIstatus::failure - Functional failed. |
| // Throws: None. |
| //-- |
| bool CMICmdCmdDataWriteMemoryBytes::Execute( void ) |
| { |
| // Do nothing - not reproduceable (yet) in Eclipse |
| //CMICMDBASE_GETOPTION( pArgOffset, OptionShort, m_constStrArgOffset ); |
| //CMICMDBASE_GETOPTION( pArgAddr, String, m_constStrArgAddr ); |
| //CMICMDBASE_GETOPTION( pArgNumber, String, m_constStrArgNumber ); |
| //CMICMDBASE_GETOPTION( pArgContents, String, m_constStrArgContents ); |
| // |
| // Numbers extracts as string types as they could be hex numbers |
| // '&' is not recognised and so has to be removed |
| |
| return MIstatus::success; |
| } |
| |
| //++ ------------------------------------------------------------------------------------ |
| // Details: The invoker requires this function. The command prepares a MI Record Result |
| // for the work carried out in the Execute(). |
| // Type: Overridden. |
| // Args: None. |
| // Return: MIstatus::success - Functional succeeded. |
| // MIstatus::failure - Functional failed. |
| // Throws: None. |
| //-- |
| bool CMICmdCmdDataWriteMemoryBytes::Acknowledge( void ) |
| { |
| const CMICmnMIValueConst miValueConst( MIRSRC( IDS_WORD_NOT_IMPLEMENTED ) ); |
| const CMICmnMIValueResult miValueResult( "msg", miValueConst ); |
| const CMICmnMIResultRecord miRecordResult( m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Error, miValueResult ); |
| m_miResultRecord = miRecordResult; |
| |
| return MIstatus::success; |
| } |
| |
| //++ ------------------------------------------------------------------------------------ |
| // Details: Required by the CMICmdFactory when registering *this command. The factory |
| // calls this function to create an instance of *this command. |
| // Type: Static method. |
| // Args: None. |
| // Return: CMICmdBase * - Pointer to a new command. |
| // Throws: None. |
| //-- |
| CMICmdBase * CMICmdCmdDataWriteMemoryBytes::CreateSelf( void ) |
| { |
| return new CMICmdCmdDataWriteMemoryBytes(); |
| } |
| |
| //--------------------------------------------------------------------------------------- |
| //--------------------------------------------------------------------------------------- |
| //--------------------------------------------------------------------------------------- |
| |
| //++ ------------------------------------------------------------------------------------ |
| // Details: CMICmdCmdDataWriteMemory constructor. |
| // Type: Method. |
| // Args: None. |
| // Return: None. |
| // Throws: None. |
| //-- |
| CMICmdCmdDataWriteMemory::CMICmdCmdDataWriteMemory( void ) |
| : m_constStrArgThread( "thread" ) |
| , m_constStrArgOffset( "o" ) |
| , m_constStrArgAddr( "address" ) |
| , m_constStrArgD( "d" ) |
| , m_constStrArgNumber( "a number" ) |
| , m_constStrArgContents( "contents" ) |
| , m_nAddr( 0 ) |
| , m_nCount( 0 ) |
| , m_pBufferMemory( nullptr ) |
| { |
| // Command factory matches this name with that received from the stdin stream |
| m_strMiCmd = "data-write-memory"; |
| |
| // Required by the CMICmdFactory when registering *this command |
| m_pSelfCreatorFn = &CMICmdCmdDataWriteMemory::CreateSelf; |
| } |
| |
| //++ ------------------------------------------------------------------------------------ |
| // Details: CMICmdCmdDataWriteMemory destructor. |
| // Type: Overrideable. |
| // Args: None. |
| // Return: None. |
| // Throws: None. |
| //-- |
| CMICmdCmdDataWriteMemory::~CMICmdCmdDataWriteMemory( void ) |
| { |
| if( m_pBufferMemory != nullptr ) |
| { |
| delete [] m_pBufferMemory; |
| m_pBufferMemory = nullptr; |
| } |
| } |
| |
| //++ ------------------------------------------------------------------------------------ |
| // Details: The invoker requires this function. The parses the command line options |
| // arguments to extract values for each of those arguments. |
| // Type: Overridden. |
| // Args: None. |
| // Return: MIstatus::success - Functional succeeded. |
| // MIstatus::failure - Functional failed. |
| // Throws: None. |
| //-- |
| bool CMICmdCmdDataWriteMemory::ParseArgs( void ) |
| { |
| bool bOk = m_setCmdArgs.Add( *(new CMICmdArgValOptionLong( m_constStrArgThread, false, false, CMICmdArgValListBase::eArgValType_Number, 1 ) ) ); |
| bOk = bOk && m_setCmdArgs.Add( *(new CMICmdArgValOptionShort( m_constStrArgOffset, false, true, CMICmdArgValListBase::eArgValType_Number, 1 ) ) ); |
| bOk = bOk && m_setCmdArgs.Add( *(new CMICmdArgValNumber( m_constStrArgAddr, true, true ) ) ); |
| bOk = bOk && m_setCmdArgs.Add( *(new CMICmdArgValString( m_constStrArgD, true, true ) ) ); |
| bOk = bOk && m_setCmdArgs.Add( *(new CMICmdArgValNumber( m_constStrArgNumber, true, true ) ) ); |
| bOk = bOk && m_setCmdArgs.Add( *(new CMICmdArgValNumber( m_constStrArgContents, true, true ) ) ); |
| CMICmdArgContext argCntxt( m_cmdData.strMiCmdOption ); |
| if( bOk && !m_setCmdArgs.Validate( m_cmdData.strMiCmd, argCntxt ) ) |
| { |
| SetError( CMIUtilString::Format( MIRSRC( IDS_CMD_ERR_ARGS ), m_cmdData.strMiCmd.c_str(), m_setCmdArgs.GetErrorDescription().c_str() ) ); |
| return MIstatus::failure; |
| } |
| |
| return bOk; |
| } |
| |
| //++ ------------------------------------------------------------------------------------ |
| // Details: The invoker requires this function. The command does work in this function. |
| // The command is likely to communicate with the LLDB SBDebugger in here. |
| // Type: Overridden. |
| // Args: None. |
| // Return: MIstatus::success - Functional succeeded. |
| // MIstatus::failure - Functional failed. |
| // Throws: None. |
| //-- |
| bool CMICmdCmdDataWriteMemory::Execute( void ) |
| { |
| CMICMDBASE_GETOPTION( pArgOffset, OptionShort, m_constStrArgOffset ); |
| CMICMDBASE_GETOPTION( pArgAddr, Number, m_constStrArgAddr ); |
| CMICMDBASE_GETOPTION( pArgNumber, Number, m_constStrArgNumber ); |
| CMICMDBASE_GETOPTION( pArgContents, Number, m_constStrArgContents ); |
| |
| MIuint nAddrOffset = 0; |
| if( pArgOffset->GetFound() && !pArgOffset->GetExpectedOption< CMICmdArgValNumber, MIuint>( nAddrOffset ) ) |
| { |
| SetError( CMIUtilString::Format( MIRSRC( IDS_CMD_ARGS_ERR_VALIDATION_INVALID ), m_cmdData.strMiCmd.c_str(), m_constStrArgAddr.c_str() ) ); |
| return MIstatus::failure; |
| } |
| m_nAddr = pArgAddr->GetValue(); |
| m_nCount = pArgNumber->GetValue(); |
| const MIuint64 nValue = pArgContents->GetValue(); |
| |
| m_pBufferMemory = new MIuchar [ m_nCount ]; |
| if( m_pBufferMemory == nullptr ) |
| { |
| SetError( CMIUtilString::Format( MIRSRC( IDS_CMD_ERR_MEMORY_ALLOC_FAILURE ), m_cmdData.strMiCmd.c_str(), m_nCount ) ); |
| return MIstatus::failure; |
| } |
| *m_pBufferMemory = static_cast< MIchar >( nValue ); |
| |
| CMICmnLLDBDebugSessionInfo & rSessionInfo( CMICmnLLDBDebugSessionInfo::Instance() ); |
| lldb::SBProcess & rProcess = rSessionInfo.m_lldbProcess; |
| lldb::SBError error; |
| lldb::addr_t addr = static_cast< lldb::addr_t >( m_nAddr + nAddrOffset ); |
| const size_t nBytesWritten = rProcess.WriteMemory( addr, (const void *) m_pBufferMemory, (size_t) m_nCount, error ); |
| if( nBytesWritten != static_cast< size_t >( m_nCount ) ) |
| { |
| SetError( CMIUtilString::Format( MIRSRC( IDS_CMD_ERR_LLDB_ERR_NOT_WRITE_WHOLEBLK ), m_cmdData.strMiCmd.c_str(), m_nCount, addr ) ); |
| return MIstatus::failure; |
| } |
| if( error.Fail() ) |
| { |
| lldb::SBStream err; |
| const bool bOk = error.GetDescription( err ); MIunused( bOk ); |
| SetError( CMIUtilString::Format( MIRSRC( IDS_CMD_ERR_LLDB_ERR_WRITE_MEM_BYTES ), m_cmdData.strMiCmd.c_str(), m_nCount, addr, err.GetData() ) ); |
| return MIstatus::failure; |
| } |
| |
| return MIstatus::success; |
| } |
| |
| //++ ------------------------------------------------------------------------------------ |
| // Details: The invoker requires this function. The command prepares a MI Record Result |
| // for the work carried out in the Execute(). |
| // Type: Overridden. |
| // Args: None. |
| // Return: MIstatus::success - Functional succeeded. |
| // MIstatus::failure - Functional failed. |
| // Throws: None. |
| //-- |
| bool CMICmdCmdDataWriteMemory::Acknowledge( void ) |
| { |
| const CMICmnMIResultRecord miRecordResult( m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Done ); |
| m_miResultRecord = miRecordResult; |
| |
| return MIstatus::success; |
| } |
| |
| //++ ------------------------------------------------------------------------------------ |
| // Details: Required by the CMICmdFactory when registering *this command. The factory |
| // calls this function to create an instance of *this command. |
| // Type: Static method. |
| // Args: None. |
| // Return: CMICmdBase * - Pointer to a new command. |
| // Throws: None. |
| //-- |
| CMICmdBase * CMICmdCmdDataWriteMemory::CreateSelf( void ) |
| { |
| return new CMICmdCmdDataWriteMemory(); |
| } |