1 //===-- MICmdCmdData.cpp ----------------------------------------*- C++ -*-===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
11 // File: MICmdCmdData.cpp
13 // Overview: CMICmdCmdDataEvaluateExpression implementation.
14 // CMICmdCmdDataDisassemble implementation.
15 // CMICmdCmdDataReadMemoryBytes implementation.
16 // CMICmdCmdDataReadMemory implementation.
17 // CMICmdCmdDataListRegisterNames implementation.
18 // CMICmdCmdDataListRegisterValues implementation.
19 // CMICmdCmdDataListRegisterChanged implementation.
20 // CMICmdCmdDataWriteMemoryBytes implementation.
21 // CMICmdCmdDataWriteMemory implementation.
23 // Environment: Compilers: Visual C++ 12.
24 // gcc (Ubuntu/Linaro 4.8.1-10ubuntu9) 4.8.1
25 // Libraries: See MIReadmetxt.
30 // Third Party Headers:
31 #include <lldb/API/SBThread.h>
32 #include <lldb/API/SBInstruction.h>
33 #include <lldb/API/SBInstructionList.h>
34 #include <lldb/API/SBStream.h>
37 #include "MICmdCmdData.h"
38 #include "MICmnMIResultRecord.h"
39 #include "MICmnMIValueConst.h"
40 #include "MICmnLLDBDebugger.h"
41 #include "MICmnLLDBDebugSessionInfo.h"
42 #include "MICmnLLDBProxySBValue.h"
43 #include "MICmdArgValNumber.h"
44 #include "MICmdArgValString.h"
45 #include "MICmdArgValThreadGrp.h"
46 #include "MICmdArgValOptionLong.h"
47 #include "MICmdArgValOptionShort.h"
48 #include "MICmdArgValListOfN.h"
49 #include "MICmdArgValConsume.h"
50 #include "MICmnLLDBDebugSessionInfoVarObj.h"
51 #include "MICmnLLDBUtilSBValue.h"
53 //++ ------------------------------------------------------------------------------------
54 // Details: CMICmdCmdDataEvaluateExpression constructor.
60 CMICmdCmdDataEvaluateExpression::CMICmdCmdDataEvaluateExpression( void )
61 : m_bExpressionValid( true )
62 , m_bEvaluatedExpression( true )
64 , m_bCompositeVarType( false )
65 , m_bFoundInvalidChar( false )
66 , m_cExpressionInvalidChar( 0x00 )
67 , m_constStrArgThread( "thread" )
68 , m_constStrArgFrame( "frame" )
69 , m_constStrArgExpr( "expr" )
71 // Command factory matches this name with that received from the stdin stream
72 m_strMiCmd = "data-evaluate-expression";
74 // Required by the CMICmdFactory when registering *this command
75 m_pSelfCreatorFn = &CMICmdCmdDataEvaluateExpression::CreateSelf;
78 //++ ------------------------------------------------------------------------------------
79 // Details: CMICmdCmdDataEvaluateExpression destructor.
80 // Type: Overrideable.
85 CMICmdCmdDataEvaluateExpression::~CMICmdCmdDataEvaluateExpression( void )
89 //++ ------------------------------------------------------------------------------------
90 // Details: The invoker requires this function. The parses the command line options
91 // arguments to extract values for each of those arguments.
94 // Return: MIstatus::success - Functional succeeded.
95 // MIstatus::failure - Functional failed.
98 bool CMICmdCmdDataEvaluateExpression::ParseArgs( void )
100 bool bOk = m_setCmdArgs.Add( *(new CMICmdArgValOptionLong( m_constStrArgThread, false, false, CMICmdArgValListBase::eArgValType_Number, 1 ) ) );
101 bOk = bOk && m_setCmdArgs.Add( *(new CMICmdArgValOptionLong( m_constStrArgFrame, false, false, CMICmdArgValListBase::eArgValType_Number, 1 ) ) );
102 bOk = bOk && m_setCmdArgs.Add( *(new CMICmdArgValString( m_constStrArgExpr, true, true, true, true ) ) );
103 return (bOk && ParseValidateCmdOptions() );
106 //++ ------------------------------------------------------------------------------------
107 // Details: The invoker requires this function. The command does work in this function.
108 // The command is likely to communicate with the LLDB SBDebugger in here.
111 // Return: MIstatus::success - Functional succeeded.
112 // MIstatus::failure - Functional failed.
115 bool CMICmdCmdDataEvaluateExpression::Execute( void )
117 CMICMDBASE_GETOPTION( pArgExpr, String, m_constStrArgExpr );
119 const CMIUtilString & rExpression( pArgExpr->GetValue() );
120 CMICmnLLDBDebugSessionInfo & rSessionInfo( CMICmnLLDBDebugSessionInfo::Instance() );
121 lldb::SBProcess & rProcess = rSessionInfo.m_lldbProcess;
122 lldb::SBThread thread = rProcess.GetSelectedThread();
123 m_bExpressionValid = (thread.GetNumFrames() > 0);
124 if( !m_bExpressionValid )
125 return MIstatus::success;
127 lldb::SBFrame frame = thread.GetSelectedFrame();
128 lldb::SBValue value = frame.EvaluateExpression( rExpression.c_str() );
129 if( !value.IsValid() )
130 value = frame.FindVariable( rExpression.c_str() );
131 if( !value.IsValid() )
133 m_bEvaluatedExpression = false;
134 return MIstatus::success;
136 const CMICmnLLDBUtilSBValue utilValue( value );
137 if( !utilValue.HasName() )
139 if( HaveInvalidCharacterInExpression( rExpression, m_cExpressionInvalidChar ) )
141 m_bFoundInvalidChar = true;
142 return MIstatus::success;
145 m_strValue = rExpression;
146 return MIstatus::success;
148 if( rExpression.IsQuoted() )
150 m_strValue = rExpression.Trim( '\"' );
151 return MIstatus::success;
154 MIuint64 nNumber = 0;
155 if( CMICmnLLDBProxySBValue::GetValueAsUnsigned( value, nNumber ) == MIstatus::success )
157 const lldb::ValueType eValueType = value.GetValueType(); MIunused( eValueType );
158 m_strValue = utilValue.GetValue();
159 CMIUtilString strCString;
160 if( CMICmnLLDBProxySBValue::GetCString( value, strCString ) )
162 m_strValue += CMIUtilString::Format( " '%s'", strCString.c_str() );
164 return MIstatus::success;
167 // Composite type i.e. struct
168 m_bCompositeVarType = true;
169 const MIuint nChild = value.GetNumChildren();
170 for( MIuint i = 0; i < nChild; i++ )
172 lldb::SBValue member = value.GetChildAtIndex( i );
173 const bool bValid = member.IsValid();
174 CMIUtilString strType( MIRSRC( IDS_WORD_UNKNOWNTYPE_BRKTS ) );
177 const CMIUtilString strValue( CMICmnLLDBDebugSessionInfoVarObj::GetValueStringFormatted( member, CMICmnLLDBDebugSessionInfoVarObj::eVarFormat_Natural ) );
178 const char * pTypeName = member.GetName();
179 if( pTypeName != nullptr )
182 // MI print "{variable = 1, variable2 = 3, variable3 = 5}"
183 const bool bNoQuotes = true;
184 const CMICmnMIValueConst miValueConst( strValue, bNoQuotes );
185 const bool bUseSpaces = true;
186 const CMICmnMIValueResult miValueResult( strType, miValueConst, bUseSpaces );
187 m_miValueTuple.Add( miValueResult, bUseSpaces );
191 return MIstatus::success;
194 //++ ------------------------------------------------------------------------------------
195 // Details: The invoker requires this function. The command prepares a MI Record Result
196 // for the work carried out in the Execute().
199 // Return: MIstatus::success - Functional succeeded.
200 // MIstatus::failure - Functional failed.
203 bool CMICmdCmdDataEvaluateExpression::Acknowledge( void )
205 if( m_bExpressionValid )
207 if( m_bEvaluatedExpression )
209 if( m_bCompositeVarType )
211 const CMICmnMIValueConst miValueConst( m_miValueTuple.GetString() );
212 const CMICmnMIValueResult miValueResult( "value", miValueConst );
213 const CMICmnMIResultRecord miRecordResult( m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Done, miValueResult );
214 m_miResultRecord = miRecordResult;
215 return MIstatus::success;
218 if( m_bFoundInvalidChar )
220 const CMICmnMIValueConst miValueConst( CMIUtilString::Format( "Invalid character '%c' in expression", m_cExpressionInvalidChar ) );
221 const CMICmnMIValueResult miValueResult( "msg", miValueConst );
222 const CMICmnMIResultRecord miRecordResult( m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Error, miValueResult );
223 m_miResultRecord = miRecordResult;
224 return MIstatus::success;
227 const CMICmnMIValueConst miValueConst( m_strValue );
228 const CMICmnMIValueResult miValueResult( "value", miValueConst );
229 const CMICmnMIResultRecord miRecordResult( m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Done, miValueResult );
230 m_miResultRecord = miRecordResult;
231 return MIstatus::success;
234 const CMICmnMIValueConst miValueConst( "Could not evaluate expression" );
235 const CMICmnMIValueResult miValueResult( "msg", miValueConst );
236 const CMICmnMIResultRecord miRecordResult( m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Error, miValueResult );
237 m_miResultRecord = miRecordResult;
238 return MIstatus::success;
241 const CMICmnMIValueConst miValueConst( "Invalid expression" );
242 const CMICmnMIValueResult miValueResult( "msg", miValueConst );
243 const CMICmnMIResultRecord miRecordResult( m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Error, miValueResult );
244 m_miResultRecord = miRecordResult;
246 return MIstatus::success;
249 //++ ------------------------------------------------------------------------------------
250 // Details: Required by the CMICmdFactory when registering *this command. The factory
251 // calls this function to create an instance of *this command.
252 // Type: Static method.
254 // Return: CMICmdBase * - Pointer to a new command.
257 CMICmdBase * CMICmdCmdDataEvaluateExpression::CreateSelf( void )
259 return new CMICmdCmdDataEvaluateExpression();
262 //++ ------------------------------------------------------------------------------------
263 // Details: Examine the expression string to see if it contains invalid characters.
265 // Args: vrExpr - (R) Expression string given to *this command.
266 // vrwInvalidChar - (W) True = Invalid character found, false = nothing found.
267 // Return: bool - True = Invalid character found, false = nothing found.
270 bool CMICmdCmdDataEvaluateExpression::HaveInvalidCharacterInExpression( const CMIUtilString & vrExpr, MIchar & vrwInvalidChar )
272 bool bFoundInvalidCharInExpression = false;
273 vrwInvalidChar = 0x00;
275 if( vrExpr.at( 0 ) == '\\' )
277 // Example: Mouse hover over "%5d" expression has \"%5d\" in it
278 bFoundInvalidCharInExpression = true;
279 vrwInvalidChar = '\\';
282 return bFoundInvalidCharInExpression;
285 //---------------------------------------------------------------------------------------
286 //---------------------------------------------------------------------------------------
287 //---------------------------------------------------------------------------------------
289 //++ ------------------------------------------------------------------------------------
290 // Details: CMICmdCmdDataDisassemble constructor.
296 CMICmdCmdDataDisassemble::CMICmdCmdDataDisassemble( void )
297 : m_constStrArgThread( "thread" )
298 , m_constStrArgAddrStart( "s" )
299 , m_constStrArgAddrEnd( "e" )
300 , m_constStrArgConsume( "--" )
301 , m_constStrArgMode( "mode" )
302 , m_miValueList( true )
304 // Command factory matches this name with that received from the stdin stream
305 m_strMiCmd = "data-disassemble";
307 // Required by the CMICmdFactory when registering *this command
308 m_pSelfCreatorFn = &CMICmdCmdDataDisassemble::CreateSelf;
311 //++ ------------------------------------------------------------------------------------
312 // Details: CMICmdCmdDataDisassemble destructor.
313 // Type: Overrideable.
318 CMICmdCmdDataDisassemble::~CMICmdCmdDataDisassemble( void )
322 //++ ------------------------------------------------------------------------------------
323 // Details: The invoker requires this function. The parses the command line options
324 // arguments to extract values for each of those arguments.
327 // Return: MIstatus::success - Functional succeeded.
328 // MIstatus::failure - Functional failed.
331 bool CMICmdCmdDataDisassemble::ParseArgs( void )
333 bool bOk = m_setCmdArgs.Add( *(new CMICmdArgValOptionLong( m_constStrArgThread, true, true, CMICmdArgValListBase::eArgValType_Number, 1 ) ) );
334 bOk = bOk && m_setCmdArgs.Add( *(new CMICmdArgValOptionShort( m_constStrArgAddrStart, true, true, CMICmdArgValListBase::eArgValType_StringQuotedNumber, 1 ) ) );
335 bOk = bOk && m_setCmdArgs.Add( *(new CMICmdArgValOptionShort( m_constStrArgAddrEnd, true, true, CMICmdArgValListBase::eArgValType_StringQuotedNumber, 1 ) ) );
336 bOk = bOk && m_setCmdArgs.Add( *(new CMICmdArgValConsume( m_constStrArgConsume, true ) ) );
337 bOk = bOk && m_setCmdArgs.Add( *(new CMICmdArgValNumber( m_constStrArgMode, true, true ) ) );
338 return (bOk && ParseValidateCmdOptions() );
341 //++ ------------------------------------------------------------------------------------
342 // Details: The invoker requires this function. The command does work in this function.
343 // The command is likely to communicate with the LLDB SBDebugger in here.
346 // Return: MIstatus::success - Functional succeeded.
347 // MIstatus::failure - Functional failed.
350 bool CMICmdCmdDataDisassemble::Execute( void )
352 CMICMDBASE_GETOPTION( pArgThread, OptionLong, m_constStrArgThread );
353 CMICMDBASE_GETOPTION( pArgAddrStart, OptionShort, m_constStrArgAddrStart );
354 CMICMDBASE_GETOPTION( pArgAddrEnd, OptionShort, m_constStrArgAddrEnd );
355 CMICMDBASE_GETOPTION( pArgMode, Number, m_constStrArgMode );
357 // Retrieve the --thread option's thread ID (only 1)
358 MIuint64 nThreadId = UINT64_MAX;
359 if( !pArgThread->GetExpectedOption< CMICmdArgValNumber, MIuint64 >( nThreadId ) )
361 SetError( CMIUtilString::Format( MIRSRC( IDS_CMD_ERR_THREAD_INVALID ), m_cmdData.strMiCmd.c_str(), m_constStrArgThread.c_str() ) );
362 return MIstatus::failure;
364 CMIUtilString strAddrStart;
365 if( !pArgAddrStart->GetExpectedOption< CMICmdArgValString, CMIUtilString >( strAddrStart ) )
367 SetError( CMIUtilString::Format( MIRSRC( IDS_CMD_ERR_DISASM_ADDR_START_INVALID ), m_cmdData.strMiCmd.c_str(), m_constStrArgAddrStart.c_str() ) );
368 return MIstatus::failure;
370 MIint64 nAddrStart = 0;
371 if( !strAddrStart.ExtractNumber( nAddrStart ) )
373 SetError( CMIUtilString::Format( MIRSRC( IDS_CMD_ERR_DISASM_ADDR_START_INVALID ), m_cmdData.strMiCmd.c_str(), m_constStrArgAddrStart.c_str() ) );
374 return MIstatus::failure;
377 CMIUtilString strAddrEnd;
378 if( !pArgAddrEnd->GetExpectedOption< CMICmdArgValString, CMIUtilString >( strAddrEnd ) )
380 SetError( CMIUtilString::Format( MIRSRC( IDS_CMD_ERR_DISASM_ADDR_END_INVALID ), m_cmdData.strMiCmd.c_str(), m_constStrArgAddrEnd.c_str() ) );
381 return MIstatus::failure;
383 MIint64 nAddrEnd = 0;
384 if( !strAddrEnd.ExtractNumber( nAddrEnd ) )
386 SetError( CMIUtilString::Format( MIRSRC( IDS_CMD_ERR_DISASM_ADDR_END_INVALID ), m_cmdData.strMiCmd.c_str(), m_constStrArgAddrEnd.c_str() ) );
387 return MIstatus::failure;
389 const MIuint nDisasmMode = pArgMode->GetValue();
391 CMICmnLLDBDebugSessionInfo & rSessionInfo( CMICmnLLDBDebugSessionInfo::Instance() );
392 lldb::SBTarget & rTarget = rSessionInfo.m_lldbTarget;
393 lldb::addr_t lldbStartAddr = static_cast< lldb::addr_t >( nAddrStart );
394 lldb::SBInstructionList instructions = rTarget.ReadInstructions( lldb::SBAddress( lldbStartAddr, rTarget ), nAddrEnd - nAddrStart );
395 const MIuint nInstructions = instructions.GetSize();
396 for( size_t i = 0; i < nInstructions; i++ )
398 const MIchar * pUnknown = "??";
399 lldb::SBInstruction instrt = instructions.GetInstructionAtIndex( i );
400 const MIchar * pStrMnemonic = instrt.GetMnemonic( rTarget );
401 pStrMnemonic = (pStrMnemonic != nullptr) ? pStrMnemonic : pUnknown;
402 lldb::SBAddress address = instrt.GetAddress();
403 lldb::addr_t addr = address.GetLoadAddress( rTarget );
404 const MIchar * pFnName = address.GetFunction().GetName();
405 pFnName = (pFnName != nullptr) ? pFnName : pUnknown;
406 lldb::addr_t addrOffSet = address.GetOffset();
407 const MIchar * pStrOperands = instrt.GetOperands( rTarget );
408 pStrOperands = (pStrOperands != nullptr) ? pStrOperands : pUnknown;
410 // MI "{address=\"0x%08llx\",func-name=\"%s\",offset=\"%lld\",inst=\"%s %s\"}"
411 const CMICmnMIValueConst miValueConst( CMIUtilString::Format( "0x%08llx", addr ) );
412 const CMICmnMIValueResult miValueResult( "address", miValueConst );
413 CMICmnMIValueTuple miValueTuple( miValueResult );
414 const CMICmnMIValueConst miValueConst2( pFnName );
415 const CMICmnMIValueResult miValueResult2( "func-name", miValueConst2 );
416 miValueTuple.Add( miValueResult2 );
417 const CMICmnMIValueConst miValueConst3( CMIUtilString::Format( "0x%lld", addrOffSet ) );
418 const CMICmnMIValueResult miValueResult3( "offset", miValueConst3 );
419 miValueTuple.Add( miValueResult3 );
420 const CMICmnMIValueConst miValueConst4( CMIUtilString::Format( "%s %s", pStrMnemonic, pStrOperands ) );
421 const CMICmnMIValueResult miValueResult4( "inst", miValueConst4 );
422 miValueTuple.Add( miValueResult4 );
424 if( nDisasmMode == 1 )
426 lldb::SBLineEntry lineEntry = address.GetLineEntry();
427 const MIuint nLine = lineEntry.GetLine();
428 const MIchar * pFileName = lineEntry.GetFileSpec().GetFilename();
429 pFileName = (pFileName != nullptr) ? pFileName : pUnknown;
431 // MI "src_and_asm_line={line=\"%u\",file=\"%s\",line_asm_insn=[ ]}"
432 const CMICmnMIValueConst miValueConst( CMIUtilString::Format( "0x%u", nLine ) );
433 const CMICmnMIValueResult miValueResult( "line", miValueConst );
434 CMICmnMIValueTuple miValueTuple2( miValueResult );
435 const CMICmnMIValueConst miValueConst2( pFileName );
436 const CMICmnMIValueResult miValueResult2( "file", miValueConst2 );
437 miValueTuple2.Add( miValueResult2 );
438 const CMICmnMIValueList miValueList( miValueTuple );
439 const CMICmnMIValueResult miValueResult3( "line_asm_insn", miValueList );
440 miValueTuple2.Add( miValueResult3 );
441 const CMICmnMIValueResult miValueResult4( "src_and_asm_line", miValueTuple2 );
442 m_miValueList.Add( miValueResult4 );
446 m_miValueList.Add( miValueTuple );
450 return MIstatus::success;
453 //++ ------------------------------------------------------------------------------------
454 // Details: The invoker requires this function. The command prepares a MI Record Result
455 // for the work carried out in the Execute().
458 // Return: MIstatus::success - Functional succeeded.
459 // MIstatus::failure - Functional failed.
462 bool CMICmdCmdDataDisassemble::Acknowledge( void )
464 const CMICmnMIValueResult miValueResult( "asm_insns", m_miValueList );
465 const CMICmnMIResultRecord miRecordResult( m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Done, miValueResult );
466 m_miResultRecord = miRecordResult;
468 return MIstatus::success;
471 //++ ------------------------------------------------------------------------------------
472 // Details: Required by the CMICmdFactory when registering *this command. The factory
473 // calls this function to create an instance of *this command.
474 // Type: Static method.
476 // Return: CMICmdBase * - Pointer to a new command.
479 CMICmdBase * CMICmdCmdDataDisassemble::CreateSelf( void )
481 return new CMICmdCmdDataDisassemble();
484 //---------------------------------------------------------------------------------------
485 //---------------------------------------------------------------------------------------
486 //---------------------------------------------------------------------------------------
488 //++ ------------------------------------------------------------------------------------
489 // Details: CMICmdCmdDataReadMemoryBytes constructor.
495 CMICmdCmdDataReadMemoryBytes::CMICmdCmdDataReadMemoryBytes( void )
496 : m_constStrArgThread( "thread" )
497 , m_constStrArgByteOffset( "o" )
498 , m_constStrArgAddrStart( "address" )
499 , m_constStrArgNumBytes( "count" )
500 , m_pBufferMemory( nullptr )
502 , m_nAddrNumBytesToRead( 0 )
505 // Command factory matches this name with that received from the stdin stream
506 m_strMiCmd = "data-read-memory-bytes";
508 // Required by the CMICmdFactory when registering *this command
509 m_pSelfCreatorFn = &CMICmdCmdDataReadMemoryBytes::CreateSelf;
512 //++ ------------------------------------------------------------------------------------
513 // Details: CMICmdCmdDataReadMemoryBytes destructor.
514 // Type: Overrideable.
519 CMICmdCmdDataReadMemoryBytes::~CMICmdCmdDataReadMemoryBytes( void )
521 if( m_pBufferMemory != nullptr )
523 delete [] m_pBufferMemory;
524 m_pBufferMemory = nullptr;
528 //++ ------------------------------------------------------------------------------------
529 // Details: The invoker requires this function. The parses the command line options
530 // arguments to extract values for each of those arguments.
533 // Return: MIstatus::success - Functional succeeded.
534 // MIstatus::failure - Functional failed.
537 bool CMICmdCmdDataReadMemoryBytes::ParseArgs( void )
539 bool bOk = m_setCmdArgs.Add( *(new CMICmdArgValOptionLong( m_constStrArgThread, false, false, CMICmdArgValListBase::eArgValType_Number, 1 ) ) );
540 bOk = bOk && m_setCmdArgs.Add( *(new CMICmdArgValOptionShort( m_constStrArgByteOffset, false, true, CMICmdArgValListBase::eArgValType_Number, 1 ) ) );
541 bOk = bOk && m_setCmdArgs.Add( *(new CMICmdArgValNumber( m_constStrArgAddrStart, true, true ) ) );
542 bOk = bOk && m_setCmdArgs.Add( *(new CMICmdArgValNumber( m_constStrArgNumBytes, true, true ) ) );
543 return (bOk && ParseValidateCmdOptions() );
546 //++ ------------------------------------------------------------------------------------
547 // Details: The invoker requires this function. The command does work in this function.
548 // The command is likely to communicate with the LLDB SBDebugger in here.
551 // Return: MIstatus::success - Functional succeeded.
552 // MIstatus::failure - Functional failed.
555 bool CMICmdCmdDataReadMemoryBytes::Execute( void )
557 CMICMDBASE_GETOPTION( pArgAddrStart, Number, m_constStrArgAddrStart );
558 CMICMDBASE_GETOPTION( pArgAddrOffset, Number, m_constStrArgByteOffset );
559 CMICMDBASE_GETOPTION( pArgNumBytes, Number, m_constStrArgNumBytes );
561 const MIuint64 nAddrStart = pArgAddrStart->GetValue();
562 const MIuint64 nAddrNumBytes = pArgNumBytes->GetValue();
563 if( pArgAddrOffset->GetFound() )
564 m_nAddrOffset = pArgAddrOffset->GetValue();
566 m_pBufferMemory = new MIuchar[ nAddrNumBytes ];
567 if( m_pBufferMemory == nullptr )
569 SetError( CMIUtilString::Format( MIRSRC( IDS_CMD_ERR_MEMORY_ALLOC_FAILURE ), m_cmdData.strMiCmd.c_str(), nAddrNumBytes ) );
570 return MIstatus::failure;
573 CMICmnLLDBDebugSessionInfo & rSessionInfo( CMICmnLLDBDebugSessionInfo::Instance() );
574 lldb::SBProcess & rProcess = rSessionInfo.m_lldbProcess;
576 const MIuint64 nReadBytes = rProcess.ReadMemory( static_cast< lldb::addr_t >( nAddrStart ), (void *) m_pBufferMemory, nAddrNumBytes, error );
577 if( nReadBytes != nAddrNumBytes )
579 SetError( CMIUtilString::Format( MIRSRC( IDS_CMD_ERR_LLDB_ERR_NOT_READ_WHOLE_BLK ), m_cmdData.strMiCmd.c_str(), nAddrNumBytes, nAddrStart ) );
580 return MIstatus::failure;
585 const bool bOk = error.GetDescription( err ); MIunused( bOk );
586 SetError( CMIUtilString::Format( MIRSRC( IDS_CMD_ERR_LLDB_ERR_READ_MEM_BYTES ), m_cmdData.strMiCmd.c_str(), nAddrNumBytes, nAddrStart, err.GetData() ) );
587 return MIstatus::failure;
590 m_nAddrStart = nAddrStart;
591 m_nAddrNumBytesToRead = nAddrNumBytes;
593 return MIstatus::success;
596 //++ ------------------------------------------------------------------------------------
597 // Details: The invoker requires this function. The command prepares a MI Record Result
598 // for the work carried out in the Execute().
601 // Return: MIstatus::success - Functional succeeded.
602 // MIstatus::failure - Functional failed.
605 bool CMICmdCmdDataReadMemoryBytes::Acknowledge( void )
607 // MI: memory=[{begin=\"0x%08x\",offset=\"0x%08x\",end=\"0x%08x\",contents=\" \" }]"
608 const CMICmnMIValueConst miValueConst( CMIUtilString::Format( "0x%08x", m_nAddrStart ) );
609 const CMICmnMIValueResult miValueResult( "begin", miValueConst );
610 CMICmnMIValueTuple miValueTuple( miValueResult );
611 const CMICmnMIValueConst miValueConst2( CMIUtilString::Format( "0x%08x", m_nAddrOffset ) );
612 const CMICmnMIValueResult miValueResult2( "offset", miValueConst2 );
613 miValueTuple.Add( miValueResult2 );
614 const CMICmnMIValueConst miValueConst3( CMIUtilString::Format( "0x%08x", m_nAddrStart + m_nAddrNumBytesToRead ) );
615 const CMICmnMIValueResult miValueResult3( "end", miValueConst3 );
616 miValueTuple.Add( miValueResult3 );
618 // MI: contents=\" \"
619 CMIUtilString strContent;
620 strContent.reserve( (m_nAddrNumBytesToRead << 1) + 1 );
621 for( MIuint64 i = 0; i < m_nAddrNumBytesToRead; i ++ )
623 strContent += CMIUtilString::Format( "%02x", m_pBufferMemory[ i ] );
625 const CMICmnMIValueConst miValueConst4( strContent );
626 const CMICmnMIValueResult miValueResult4( "contents", miValueConst4 );
627 miValueTuple.Add( miValueResult4 );
628 const CMICmnMIValueList miValueList( miValueTuple );
629 const CMICmnMIValueResult miValueResult5( "memory", miValueList );
631 const CMICmnMIResultRecord miRecordResult( m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Done, miValueResult5 );
632 m_miResultRecord = miRecordResult;
634 return MIstatus::success;
637 //++ ------------------------------------------------------------------------------------
638 // Details: Required by the CMICmdFactory when registering *this command. The factory
639 // calls this function to create an instance of *this command.
640 // Type: Static method.
642 // Return: CMICmdBase * - Pointer to a new command.
645 CMICmdBase * CMICmdCmdDataReadMemoryBytes::CreateSelf( void )
647 return new CMICmdCmdDataReadMemoryBytes();
650 //---------------------------------------------------------------------------------------
651 //---------------------------------------------------------------------------------------
652 //---------------------------------------------------------------------------------------
654 //++ ------------------------------------------------------------------------------------
655 // Details: CMICmdCmdDataReadMemory constructor.
661 CMICmdCmdDataReadMemory::CMICmdCmdDataReadMemory( void )
663 // Command factory matches this name with that received from the stdin stream
664 m_strMiCmd = "data-read-memory";
666 // Required by the CMICmdFactory when registering *this command
667 m_pSelfCreatorFn = &CMICmdCmdDataReadMemory::CreateSelf;
670 //++ ------------------------------------------------------------------------------------
671 // Details: CMICmdCmdDataReadMemory destructor.
672 // Type: Overrideable.
677 CMICmdCmdDataReadMemory::~CMICmdCmdDataReadMemory( void )
681 //++ ------------------------------------------------------------------------------------
682 // Details: The invoker requires this function. The command does work in this function.
683 // The command is likely to communicate with the LLDB SBDebugger in here.
686 // Return: MIstatus::success - Functional succeeded.
687 // MIstatus::failure - Functional failed.
690 bool CMICmdCmdDataReadMemory::Execute( void )
692 // Do nothing - command deprecated use "data-read-memory-bytes" command
693 return MIstatus::success;
696 //++ ------------------------------------------------------------------------------------
697 // Details: The invoker requires this function. The command prepares a MI Record Result
698 // for the work carried out in the Execute().
701 // Return: MIstatus::success - Functional succeeded.
702 // MIstatus::failure - Functional failed.
705 bool CMICmdCmdDataReadMemory::Acknowledge( void )
707 // Command CMICmdCmdSupportListFeatures sends "data-read-memory-bytes" which causes this command not to be called
708 const CMICmnMIValueConst miValueConst( MIRSRC( IDS_CMD_ERR_NOT_IMPLEMENTED_DEPRECATED ) );
709 const CMICmnMIValueResult miValueResult( "msg", miValueConst );
710 const CMICmnMIResultRecord miRecordResult( m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Error, miValueResult );
711 m_miResultRecord = miRecordResult;
713 return MIstatus::success;
716 //++ ------------------------------------------------------------------------------------
717 // Details: Required by the CMICmdFactory when registering *this command. The factory
718 // calls this function to create an instance of *this command.
719 // Type: Static method.
721 // Return: CMICmdBase * - Pointer to a new command.
724 CMICmdBase * CMICmdCmdDataReadMemory::CreateSelf( void )
726 return new CMICmdCmdDataReadMemory();
729 //---------------------------------------------------------------------------------------
730 //---------------------------------------------------------------------------------------
731 //---------------------------------------------------------------------------------------
733 //++ ------------------------------------------------------------------------------------
734 // Details: CMICmdCmdDataListRegisterNames constructor.
740 CMICmdCmdDataListRegisterNames::CMICmdCmdDataListRegisterNames( void )
741 : m_constStrArgThreadGroup( "thread-group" )
742 , m_constStrArgRegNo( "regno" )
743 , m_miValueList( true )
745 // Command factory matches this name with that received from the stdin stream
746 m_strMiCmd = "data-list-register-names";
748 // Required by the CMICmdFactory when registering *this command
749 m_pSelfCreatorFn = &CMICmdCmdDataListRegisterNames::CreateSelf;
752 //++ ------------------------------------------------------------------------------------
753 // Details: CMICmdCmdDataReadMemoryBytes destructor.
754 // Type: Overrideable.
759 CMICmdCmdDataListRegisterNames::~CMICmdCmdDataListRegisterNames( void )
763 //++ ------------------------------------------------------------------------------------
764 // Details: The invoker requires this function. The parses the command line options
765 // arguments to extract values for each of those arguments.
768 // Return: MIstatus::success - Functional succeeded.
769 // MIstatus::failure - Functional failed.
772 bool CMICmdCmdDataListRegisterNames::ParseArgs( void )
774 bool bOk = m_setCmdArgs.Add( *(new CMICmdArgValOptionLong( m_constStrArgThreadGroup, false, false, CMICmdArgValListBase::eArgValType_ThreadGrp, 1 ) ) );
775 bOk = bOk && m_setCmdArgs.Add( *(new CMICmdArgValListOfN( m_constStrArgRegNo, false, false, CMICmdArgValListBase::eArgValType_Number ) ) );
776 return (bOk && ParseValidateCmdOptions() );
779 //++ ------------------------------------------------------------------------------------
780 // Details: The invoker requires this function. The command does work in this function.
781 // The command is likely to communicate with the LLDB SBDebugger in here.
784 // Return: MIstatus::success - Functional succeeded.
785 // MIstatus::failure - Functional failed.
788 bool CMICmdCmdDataListRegisterNames::Execute( void )
790 CMICmnLLDBDebugSessionInfo & rSessionInfo( CMICmnLLDBDebugSessionInfo::Instance() );
791 lldb::SBProcess & rProcess = rSessionInfo.m_lldbProcess;
792 if( !rProcess.IsValid() )
794 SetError( CMIUtilString::Format( MIRSRC( IDS_CMD_ERR_INVALID_PROCESS ), m_cmdData.strMiCmd.c_str() ) );
795 return MIstatus::failure;
798 lldb::SBThread thread = rProcess.GetSelectedThread();
799 lldb::SBFrame frame = thread.GetSelectedFrame();
800 lldb::SBValueList registers = frame.GetRegisters();
801 const MIuint nRegisters = registers.GetSize();
802 for( MIuint i = 0; i < nRegisters; i++ )
804 lldb::SBValue value = registers.GetValueAtIndex( i );
805 const MIuint nRegChildren = value.GetNumChildren();
806 for( MIuint j = 0; j < nRegChildren; j++ )
808 lldb::SBValue value2 = value.GetChildAtIndex( j );
809 if( value2.IsValid() )
811 const CMICmnMIValueConst miValueConst( CMICmnLLDBUtilSBValue( value2 ).GetName() );
812 m_miValueList.Add( miValueConst );
817 return MIstatus::success;
820 //++ ------------------------------------------------------------------------------------
821 // Details: The invoker requires this function. The command prepares a MI Record Result
822 // for the work carried out in the Execute().
825 // Return: MIstatus::success - Functional succeeded.
826 // MIstatus::failure - Functional failed.
829 bool CMICmdCmdDataListRegisterNames::Acknowledge( void )
831 const CMICmnMIValueResult miValueResult( "register-names", m_miValueList );
832 const CMICmnMIResultRecord miRecordResult( m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Done, miValueResult );
833 m_miResultRecord = miRecordResult;
835 return MIstatus::success;
838 //++ ------------------------------------------------------------------------------------
839 // Details: Required by the CMICmdFactory when registering *this command. The factory
840 // calls this function to create an instance of *this command.
841 // Type: Static method.
843 // Return: CMICmdBase * - Pointer to a new command.
846 CMICmdBase * CMICmdCmdDataListRegisterNames::CreateSelf( void )
848 return new CMICmdCmdDataListRegisterNames();
851 //---------------------------------------------------------------------------------------
852 //---------------------------------------------------------------------------------------
853 //---------------------------------------------------------------------------------------
855 //++ ------------------------------------------------------------------------------------
856 // Details: CMICmdCmdDataListRegisterValues constructor.
862 CMICmdCmdDataListRegisterValues::CMICmdCmdDataListRegisterValues( void )
863 : m_constStrArgThread( "thread" )
864 , m_constStrArgSkip( "skip-unavailable" )
865 , m_constStrArgFormat( "fmt" )
866 , m_constStrArgRegNo( "regno" )
867 , m_miValueList( true )
868 , m_pProcess( nullptr )
870 // Command factory matches this name with that received from the stdin stream
871 m_strMiCmd = "data-list-register-values";
873 // Required by the CMICmdFactory when registering *this command
874 m_pSelfCreatorFn = &CMICmdCmdDataListRegisterValues::CreateSelf;
877 //++ ------------------------------------------------------------------------------------
878 // Details: CMICmdCmdDataListRegisterValues destructor.
879 // Type: Overrideable.
884 CMICmdCmdDataListRegisterValues::~CMICmdCmdDataListRegisterValues( void )
888 //++ ------------------------------------------------------------------------------------
889 // Details: The invoker requires this function. The parses the command line options
890 // arguments to extract values for each of those arguments.
893 // Return: MIstatus::success - Functional succeeded.
894 // MIstatus::failure - Functional failed.
897 bool CMICmdCmdDataListRegisterValues::ParseArgs( void )
899 bool bOk = m_setCmdArgs.Add( *(new CMICmdArgValOptionLong( m_constStrArgThread, false, false, CMICmdArgValListBase::eArgValType_Number, 1 ) ) );
900 bOk = bOk && m_setCmdArgs.Add( *(new CMICmdArgValOptionLong( m_constStrArgSkip, false, false ) ) );
901 bOk = bOk && m_setCmdArgs.Add( *(new CMICmdArgValString( m_constStrArgFormat, true, true ) ) );
902 bOk = bOk && m_setCmdArgs.Add( *(new CMICmdArgValListOfN( m_constStrArgRegNo, false, true, CMICmdArgValListBase::eArgValType_Number ) ) );
903 return (bOk && ParseValidateCmdOptions() );
906 //++ ------------------------------------------------------------------------------------
907 // Details: The invoker requires this function. The command does work in this function.
908 // The command is likely to communicate with the LLDB SBDebugger in here.
911 // Return: MIstatus::success - Functional succeeded.
912 // MIstatus::failure - Functional failed.
915 bool CMICmdCmdDataListRegisterValues::Execute( void )
917 CMICMDBASE_GETOPTION( pArgFormat, String, m_constStrArgFormat );
918 CMICMDBASE_GETOPTION( pArgRegNo, ListOfN, m_constStrArgRegNo );
920 const CMIUtilString & rStrFormat( pArgFormat->GetValue() );
921 if( rStrFormat.length() != 1 )
923 SetError( CMIUtilString::Format( MIRSRC( IDS_CMD_ERR_INVALID_FORMAT_TYPE ), m_cmdData.strMiCmd.c_str(), rStrFormat.c_str() ) );
924 return MIstatus::failure;
926 const CMICmnLLDBDebugSessionInfoVarObj::varFormat_e eFormat = CMICmnLLDBDebugSessionInfoVarObj::GetVarFormatForChar( rStrFormat[ 0 ] );
927 if( eFormat == CMICmnLLDBDebugSessionInfoVarObj::eVarFormat_Invalid )
929 SetError( CMIUtilString::Format( MIRSRC( IDS_CMD_ERR_INVALID_FORMAT_TYPE ), m_cmdData.strMiCmd.c_str(), rStrFormat.c_str() ) );
930 return MIstatus::failure;
933 CMICmnLLDBDebugSessionInfo & rSessionInfo( CMICmnLLDBDebugSessionInfo::Instance() );
934 lldb::SBProcess & rProcess = rSessionInfo.m_lldbProcess;
935 if( !rProcess.IsValid() )
937 SetError( CMIUtilString::Format( MIRSRC( IDS_CMD_ERR_INVALID_PROCESS ), m_cmdData.strMiCmd.c_str() ) );
938 return MIstatus::failure;
940 m_pProcess = &rProcess;
942 const CMICmdArgValListBase::VecArgObjPtr_t & rVecRegNo( pArgRegNo->GetExpectedOptions() );
943 CMICmdArgValListBase::VecArgObjPtr_t::const_iterator it = rVecRegNo.begin();
944 while( it != rVecRegNo.end() )
946 const CMICmdArgValNumber * pRegNo = static_cast< CMICmdArgValNumber * >( *it );
947 const MIuint nReg = pRegNo->GetValue();
948 lldb::SBValue regValue = GetRegister( nReg );
949 const CMIUtilString strRegValue( CMICmnLLDBDebugSessionInfoVarObj::GetValueStringFormatted( regValue, eFormat ) );
951 const CMICmnMIValueConst miValueConst( CMIUtilString::Format( "%u", nReg ) );
952 const CMICmnMIValueResult miValueResult( "number", miValueConst );
953 CMICmnMIValueTuple miValueTuple( miValueResult );
954 const CMICmnMIValueConst miValueConst2( strRegValue );
955 const CMICmnMIValueResult miValueResult2( "value", miValueConst2 );
956 miValueTuple.Add( miValueResult2 );
957 m_miValueList.Add( miValueTuple );
963 return MIstatus::success;
966 //++ ------------------------------------------------------------------------------------
967 // Details: The invoker requires this function. The command prepares a MI Record Result
968 // for the work carried out in the Execute().
971 // Return: MIstatus::success - Functional succeeded.
972 // MIstatus::failure - Functional failed.
975 bool CMICmdCmdDataListRegisterValues::Acknowledge( void )
977 const CMICmnMIValueResult miValueResult( "register-values", m_miValueList );
978 const CMICmnMIResultRecord miRecordResult( m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Done, miValueResult );
979 m_miResultRecord = miRecordResult;
981 return MIstatus::success;
984 //++ ------------------------------------------------------------------------------------
985 // Details: Required by the CMICmdFactory when registering *this command. The factory
986 // calls this function to create an instance of *this command.
987 // Type: Static method.
989 // Return: CMICmdBase * - Pointer to a new command.
992 CMICmdBase * CMICmdCmdDataListRegisterValues::CreateSelf( void )
994 return new CMICmdCmdDataListRegisterValues();
997 //++ ------------------------------------------------------------------------------------
998 // Details: Required by the CMICmdFactory when registering *this command. The factory
999 // calls this function to create an instance of *this command.
1002 // Return: lldb::SBValue - LLDB SBValue object.
1005 lldb::SBValue CMICmdCmdDataListRegisterValues::GetRegister( const MIuint vRegisterIndex ) const
1007 lldb::SBThread thread = m_pProcess->GetSelectedThread();
1008 lldb::SBFrame frame = thread.GetSelectedFrame();
1009 lldb::SBValueList registers = frame.GetRegisters();
1010 const MIuint nRegisters = registers.GetSize();
1011 for( MIuint i = 0; i < nRegisters; i++ )
1013 lldb::SBValue value = registers.GetValueAtIndex( i );
1014 const MIuint nRegChildren = value.GetNumChildren();
1015 if( nRegChildren > 0 )
1017 lldb::SBValue value2 = value.GetChildAtIndex( vRegisterIndex );
1018 if( value2.IsValid() )
1025 return lldb::SBValue();
1028 //---------------------------------------------------------------------------------------
1029 //---------------------------------------------------------------------------------------
1030 //---------------------------------------------------------------------------------------
1032 //++ ------------------------------------------------------------------------------------
1033 // Details: CMICmdCmdDataListRegisterChanged constructor.
1039 CMICmdCmdDataListRegisterChanged::CMICmdCmdDataListRegisterChanged( void )
1041 // Command factory matches this name with that received from the stdin stream
1042 m_strMiCmd = "data-list-changed-registers";
1044 // Required by the CMICmdFactory when registering *this command
1045 m_pSelfCreatorFn = &CMICmdCmdDataListRegisterChanged::CreateSelf;
1048 //++ ------------------------------------------------------------------------------------
1049 // Details: CMICmdCmdDataListRegisterChanged destructor.
1050 // Type: Overrideable.
1055 CMICmdCmdDataListRegisterChanged::~CMICmdCmdDataListRegisterChanged( void )
1059 //++ ------------------------------------------------------------------------------------
1060 // Details: The invoker requires this function. The command does work in this function.
1061 // The command is likely to communicate with the LLDB SBDebugger in here.
1062 // Type: Overridden.
1064 // Return: MIstatus::success - Functional succeeded.
1065 // MIstatus::failure - Functional failed.
1068 bool CMICmdCmdDataListRegisterChanged::Execute( void )
1072 return MIstatus::success;
1075 //++ ------------------------------------------------------------------------------------
1076 // Details: The invoker requires this function. The command prepares a MI Record Result
1077 // for the work carried out in the Execute().
1078 // Type: Overridden.
1080 // Return: MIstatus::success - Functional succeeded.
1081 // MIstatus::failure - Functional failed.
1084 bool CMICmdCmdDataListRegisterChanged::Acknowledge( void )
1086 const CMICmnMIValueConst miValueConst( MIRSRC( IDS_WORD_NOT_IMPLEMENTED ) );
1087 const CMICmnMIValueResult miValueResult( "msg", miValueConst );
1088 const CMICmnMIResultRecord miRecordResult( m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Error, miValueResult );
1089 m_miResultRecord = miRecordResult;
1091 return MIstatus::success;
1094 //++ ------------------------------------------------------------------------------------
1095 // Details: Required by the CMICmdFactory when registering *this command. The factory
1096 // calls this function to create an instance of *this command.
1097 // Type: Static method.
1099 // Return: CMICmdBase * - Pointer to a new command.
1102 CMICmdBase * CMICmdCmdDataListRegisterChanged::CreateSelf( void )
1104 return new CMICmdCmdDataListRegisterChanged();
1107 //---------------------------------------------------------------------------------------
1108 //---------------------------------------------------------------------------------------
1109 //---------------------------------------------------------------------------------------
1111 //++ ------------------------------------------------------------------------------------
1112 // Details: CMICmdCmdDataWriteMemoryBytes constructor.
1118 CMICmdCmdDataWriteMemoryBytes::CMICmdCmdDataWriteMemoryBytes( void )
1119 : m_constStrArgThread( "thread" )
1120 , m_constStrArgAddr( "address" )
1121 , m_constStrArgContents( "contents" )
1122 , m_constStrArgCount( "count" )
1126 // Command factory matches this name with that received from the stdin stream
1127 m_strMiCmd = "data-write-memory-bytes";
1129 // Required by the CMICmdFactory when registering *this command
1130 m_pSelfCreatorFn = &CMICmdCmdDataWriteMemoryBytes::CreateSelf;
1133 //++ ------------------------------------------------------------------------------------
1134 // Details: CMICmdCmdDataWriteMemoryBytes destructor.
1135 // Type: Overrideable.
1140 CMICmdCmdDataWriteMemoryBytes::~CMICmdCmdDataWriteMemoryBytes( void )
1144 //++ ------------------------------------------------------------------------------------
1145 // Details: The invoker requires this function. The parses the command line options
1146 // arguments to extract values for each of those arguments.
1147 // Type: Overridden.
1149 // Return: MIstatus::success - Functional succeeded.
1150 // MIstatus::failure - Functional failed.
1153 bool CMICmdCmdDataWriteMemoryBytes::ParseArgs( void )
1155 bool bOk = m_setCmdArgs.Add( *(new CMICmdArgValOptionLong( m_constStrArgThread, false, false, CMICmdArgValListBase::eArgValType_Number, 1 ) ) );
1156 bOk = bOk && m_setCmdArgs.Add( *(new CMICmdArgValString( m_constStrArgAddr, true, true, false, true ) ) );
1157 bOk = bOk && m_setCmdArgs.Add( *(new CMICmdArgValString( m_constStrArgContents, true, true, true, true ) ) );
1158 bOk = bOk && m_setCmdArgs.Add( *(new CMICmdArgValString( m_constStrArgCount, false, true, false, true ) ) );
1159 return (bOk && ParseValidateCmdOptions() );
1162 //++ ------------------------------------------------------------------------------------
1163 // Details: The invoker requires this function. The command does work in this function.
1164 // The command is likely to communicate with the LLDB SBDebugger in here.
1165 // Type: Overridden.
1167 // Return: MIstatus::success - Functional succeeded.
1168 // MIstatus::failure - Functional failed.
1171 bool CMICmdCmdDataWriteMemoryBytes::Execute( void )
1173 // Do nothing - not reproduceable (yet) in Eclipse
1174 //CMICMDBASE_GETOPTION( pArgOffset, OptionShort, m_constStrArgOffset );
1175 //CMICMDBASE_GETOPTION( pArgAddr, String, m_constStrArgAddr );
1176 //CMICMDBASE_GETOPTION( pArgNumber, String, m_constStrArgNumber );
1177 //CMICMDBASE_GETOPTION( pArgContents, String, m_constStrArgContents );
1179 // Numbers extracts as string types as they could be hex numbers
1180 // '&' is not recognised and so has to be removed
1182 return MIstatus::success;
1185 //++ ------------------------------------------------------------------------------------
1186 // Details: The invoker requires this function. The command prepares a MI Record Result
1187 // for the work carried out in the Execute().
1188 // Type: Overridden.
1190 // Return: MIstatus::success - Functional succeeded.
1191 // MIstatus::failure - Functional failed.
1194 bool CMICmdCmdDataWriteMemoryBytes::Acknowledge( void )
1196 const CMICmnMIValueConst miValueConst( MIRSRC( IDS_WORD_NOT_IMPLEMENTED ) );
1197 const CMICmnMIValueResult miValueResult( "msg", miValueConst );
1198 const CMICmnMIResultRecord miRecordResult( m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Error, miValueResult );
1199 m_miResultRecord = miRecordResult;
1201 return MIstatus::success;
1204 //++ ------------------------------------------------------------------------------------
1205 // Details: Required by the CMICmdFactory when registering *this command. The factory
1206 // calls this function to create an instance of *this command.
1207 // Type: Static method.
1209 // Return: CMICmdBase * - Pointer to a new command.
1212 CMICmdBase * CMICmdCmdDataWriteMemoryBytes::CreateSelf( void )
1214 return new CMICmdCmdDataWriteMemoryBytes();
1217 //---------------------------------------------------------------------------------------
1218 //---------------------------------------------------------------------------------------
1219 //---------------------------------------------------------------------------------------
1221 //++ ------------------------------------------------------------------------------------
1222 // Details: CMICmdCmdDataWriteMemory constructor.
1228 CMICmdCmdDataWriteMemory::CMICmdCmdDataWriteMemory( void )
1229 : m_constStrArgThread( "thread" )
1230 , m_constStrArgOffset( "o" )
1231 , m_constStrArgAddr( "address" )
1232 , m_constStrArgD( "d" )
1233 , m_constStrArgNumber( "a number" )
1234 , m_constStrArgContents( "contents" )
1237 , m_pBufferMemory( nullptr )
1239 // Command factory matches this name with that received from the stdin stream
1240 m_strMiCmd = "data-write-memory";
1242 // Required by the CMICmdFactory when registering *this command
1243 m_pSelfCreatorFn = &CMICmdCmdDataWriteMemory::CreateSelf;
1246 //++ ------------------------------------------------------------------------------------
1247 // Details: CMICmdCmdDataWriteMemory destructor.
1248 // Type: Overrideable.
1253 CMICmdCmdDataWriteMemory::~CMICmdCmdDataWriteMemory( void )
1255 if( m_pBufferMemory != nullptr )
1257 delete [] m_pBufferMemory;
1258 m_pBufferMemory = nullptr;
1262 //++ ------------------------------------------------------------------------------------
1263 // Details: The invoker requires this function. The parses the command line options
1264 // arguments to extract values for each of those arguments.
1265 // Type: Overridden.
1267 // Return: MIstatus::success - Functional succeeded.
1268 // MIstatus::failure - Functional failed.
1271 bool CMICmdCmdDataWriteMemory::ParseArgs( void )
1273 bool bOk = m_setCmdArgs.Add( *(new CMICmdArgValOptionLong( m_constStrArgThread, false, false, CMICmdArgValListBase::eArgValType_Number, 1 ) ) );
1274 bOk = bOk && m_setCmdArgs.Add( *(new CMICmdArgValOptionShort( m_constStrArgOffset, false, true, CMICmdArgValListBase::eArgValType_Number, 1 ) ) );
1275 bOk = bOk && m_setCmdArgs.Add( *(new CMICmdArgValNumber( m_constStrArgAddr, true, true ) ) );
1276 bOk = bOk && m_setCmdArgs.Add( *(new CMICmdArgValString( m_constStrArgD, true, true ) ) );
1277 bOk = bOk && m_setCmdArgs.Add( *(new CMICmdArgValNumber( m_constStrArgNumber, true, true ) ) );
1278 bOk = bOk && m_setCmdArgs.Add( *(new CMICmdArgValNumber( m_constStrArgContents, true, true ) ) );
1279 return (bOk && ParseValidateCmdOptions() );
1282 //++ ------------------------------------------------------------------------------------
1283 // Details: The invoker requires this function. The command does work in this function.
1284 // The command is likely to communicate with the LLDB SBDebugger in here.
1285 // Type: Overridden.
1287 // Return: MIstatus::success - Functional succeeded.
1288 // MIstatus::failure - Functional failed.
1291 bool CMICmdCmdDataWriteMemory::Execute( void )
1293 CMICMDBASE_GETOPTION( pArgOffset, OptionShort, m_constStrArgOffset );
1294 CMICMDBASE_GETOPTION( pArgAddr, Number, m_constStrArgAddr );
1295 CMICMDBASE_GETOPTION( pArgNumber, Number, m_constStrArgNumber );
1296 CMICMDBASE_GETOPTION( pArgContents, Number, m_constStrArgContents );
1298 MIuint nAddrOffset = 0;
1299 if( pArgOffset->GetFound() && !pArgOffset->GetExpectedOption< CMICmdArgValNumber, MIuint>( nAddrOffset ) )
1301 SetError( CMIUtilString::Format( MIRSRC( IDS_CMD_ARGS_ERR_VALIDATION_INVALID ), m_cmdData.strMiCmd.c_str(), m_constStrArgAddr.c_str() ) );
1302 return MIstatus::failure;
1304 m_nAddr = pArgAddr->GetValue();
1305 m_nCount = pArgNumber->GetValue();
1306 const MIuint64 nValue = pArgContents->GetValue();
1308 m_pBufferMemory = new MIuchar [ m_nCount ];
1309 if( m_pBufferMemory == nullptr )
1311 SetError( CMIUtilString::Format( MIRSRC( IDS_CMD_ERR_MEMORY_ALLOC_FAILURE ), m_cmdData.strMiCmd.c_str(), m_nCount ) );
1312 return MIstatus::failure;
1314 *m_pBufferMemory = static_cast< MIchar >( nValue );
1316 CMICmnLLDBDebugSessionInfo & rSessionInfo( CMICmnLLDBDebugSessionInfo::Instance() );
1317 lldb::SBProcess & rProcess = rSessionInfo.m_lldbProcess;
1318 lldb::SBError error;
1319 lldb::addr_t addr = static_cast< lldb::addr_t >( m_nAddr + nAddrOffset );
1320 const size_t nBytesWritten = rProcess.WriteMemory( addr, (const void *) m_pBufferMemory, (size_t) m_nCount, error );
1321 if( nBytesWritten != static_cast< size_t >( m_nCount ) )
1323 SetError( CMIUtilString::Format( MIRSRC( IDS_CMD_ERR_LLDB_ERR_NOT_WRITE_WHOLEBLK ), m_cmdData.strMiCmd.c_str(), m_nCount, addr ) );
1324 return MIstatus::failure;
1329 const bool bOk = error.GetDescription( err ); MIunused( bOk );
1330 SetError( CMIUtilString::Format( MIRSRC( IDS_CMD_ERR_LLDB_ERR_WRITE_MEM_BYTES ), m_cmdData.strMiCmd.c_str(), m_nCount, addr, err.GetData() ) );
1331 return MIstatus::failure;
1334 return MIstatus::success;
1337 //++ ------------------------------------------------------------------------------------
1338 // Details: The invoker requires this function. The command prepares a MI Record Result
1339 // for the work carried out in the Execute().
1340 // Type: Overridden.
1342 // Return: MIstatus::success - Functional succeeded.
1343 // MIstatus::failure - Functional failed.
1346 bool CMICmdCmdDataWriteMemory::Acknowledge( void )
1348 const CMICmnMIResultRecord miRecordResult( m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Done );
1349 m_miResultRecord = miRecordResult;
1351 return MIstatus::success;
1354 //++ ------------------------------------------------------------------------------------
1355 // Details: Required by the CMICmdFactory when registering *this command. The factory
1356 // calls this function to create an instance of *this command.
1357 // Type: Static method.
1359 // Return: CMICmdBase * - Pointer to a new command.
1362 CMICmdBase * CMICmdCmdDataWriteMemory::CreateSelf( void )
1364 return new CMICmdCmdDataWriteMemory();