]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - tools/lldb-mi/MICmdCmdData.cpp
Import LLDB as of upstream SVN r216948 (git 50f7fe44)
[FreeBSD/FreeBSD.git] / tools / lldb-mi / MICmdCmdData.cpp
1 //===-- MICmdCmdData.cpp ----------------------------------------*- C++ -*-===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9
10 //++
11 // File:                MICmdCmdData.cpp
12 //
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.
22 //
23 // Environment: Compilers:      Visual C++ 12.
24 //                                                      gcc (Ubuntu/Linaro 4.8.1-10ubuntu9) 4.8.1
25 //                              Libraries:      See MIReadmetxt. 
26 //
27 // Copyright:   None.
28 //--
29
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>
35
36 // In-house headers:
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"
52
53 //++ ------------------------------------------------------------------------------------
54 // Details:     CMICmdCmdDataEvaluateExpression constructor.
55 // Type:        Method.
56 // Args:        None.
57 // Return:      None.
58 // Throws:      None.
59 //--
60 CMICmdCmdDataEvaluateExpression::CMICmdCmdDataEvaluateExpression( void )
61 :       m_bExpressionValid( true )
62 ,       m_bEvaluatedExpression( true )
63 ,       m_strValue( "??" )
64 ,       m_bCompositeVarType( false )
65 ,       m_bFoundInvalidChar( false )
66 ,       m_cExpressionInvalidChar( 0x00 )
67 ,       m_constStrArgThread( "thread" )
68 ,       m_constStrArgFrame( "frame" )
69 ,       m_constStrArgExpr( "expr" )
70 {
71         // Command factory matches this name with that received from the stdin stream
72         m_strMiCmd = "data-evaluate-expression";
73         
74         // Required by the CMICmdFactory when registering *this command
75         m_pSelfCreatorFn = &CMICmdCmdDataEvaluateExpression::CreateSelf;
76 }
77
78 //++ ------------------------------------------------------------------------------------
79 // Details:     CMICmdCmdDataEvaluateExpression destructor.
80 // Type:        Overrideable.
81 // Args:        None.
82 // Return:      None.
83 // Throws:      None.
84 //--
85 CMICmdCmdDataEvaluateExpression::~CMICmdCmdDataEvaluateExpression( void )
86 {
87 }
88
89 //++ ------------------------------------------------------------------------------------
90 // Details:     The invoker requires this function. The parses the command line options 
91 //                      arguments to extract values for each of those arguments.
92 // Type:        Overridden.
93 // Args:        None.
94 // Return:      MIstatus::success - Functional succeeded.
95 //                      MIstatus::failure - Functional failed.
96 // Throws:      None.
97 //--
98 bool CMICmdCmdDataEvaluateExpression::ParseArgs( void )
99 {
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() );
104 }
105
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.
109 // Type:        Overridden.
110 // Args:        None.
111 // Return:      MIstatus::success - Functional succeeded.
112 //                      MIstatus::failure - Functional failed.
113 // Throws:      None.
114 //--
115 bool CMICmdCmdDataEvaluateExpression::Execute( void )
116 {
117         CMICMDBASE_GETOPTION( pArgExpr, String, m_constStrArgExpr );
118
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;
126         
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() )
132         {
133                 m_bEvaluatedExpression = false;
134                 return MIstatus::success;
135         }
136         const CMICmnLLDBUtilSBValue utilValue( value );
137         if( !utilValue.HasName() )
138         {
139                 if( HaveInvalidCharacterInExpression( rExpression, m_cExpressionInvalidChar ) )
140                 {
141                         m_bFoundInvalidChar = true;
142                         return MIstatus::success;
143                 }
144
145                 m_strValue = rExpression;
146                 return MIstatus::success;
147         }
148         if( rExpression.IsQuoted() )
149         {
150                 m_strValue = rExpression.Trim( '\"' );
151                 return MIstatus::success;
152         }
153
154         MIuint64 nNumber = 0;
155         if( CMICmnLLDBProxySBValue::GetValueAsUnsigned( value, nNumber ) == MIstatus::success )
156         {
157                 const lldb::ValueType eValueType = value.GetValueType(); MIunused( eValueType );
158                 m_strValue = utilValue.GetValue();
159                 CMIUtilString strCString;
160                 if( CMICmnLLDBProxySBValue::GetCString( value, strCString ) )
161                 {
162                         m_strValue += CMIUtilString::Format( " '%s'", strCString.c_str() );
163                 }
164                 return MIstatus::success;
165         }
166
167         // Composite type i.e. struct
168         m_bCompositeVarType = true;
169         const MIuint nChild = value.GetNumChildren();
170         for( MIuint i = 0; i < nChild; i++ )
171         {
172                 lldb::SBValue member = value.GetChildAtIndex( i );
173                 const bool bValid = member.IsValid();
174                 CMIUtilString strType( MIRSRC( IDS_WORD_UNKNOWNTYPE_BRKTS ) );
175                 if( bValid )
176                 {
177                         const CMIUtilString strValue( CMICmnLLDBDebugSessionInfoVarObj::GetValueStringFormatted( member, CMICmnLLDBDebugSessionInfoVarObj::eVarFormat_Natural ) );
178                         const char * pTypeName = member.GetName();
179                         if( pTypeName != nullptr )
180                                 strType = pTypeName;
181
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 );
188                 }
189         }
190                 
191         return MIstatus::success;
192 }
193
194 //++ ------------------------------------------------------------------------------------
195 // Details:     The invoker requires this function. The command prepares a MI Record Result
196 //                      for the work carried out in the Execute().
197 // Type:        Overridden.
198 // Args:        None.
199 // Return:      MIstatus::success - Functional succeeded.
200 //                      MIstatus::failure - Functional failed.
201 // Throws:      None.
202 //--
203 bool CMICmdCmdDataEvaluateExpression::Acknowledge( void )
204 {
205         if( m_bExpressionValid )
206         {
207                 if( m_bEvaluatedExpression )
208                 {
209                         if( m_bCompositeVarType )
210                         {
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;
216                         }
217
218                         if( m_bFoundInvalidChar )
219                         {
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;
225                         }
226                         
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;
232                 }
233
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;
239         }
240
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;
245         
246         return MIstatus::success;
247 }
248
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.
253 // Args:        None.
254 // Return:      CMICmdBase * - Pointer to a new command.
255 // Throws:      None.
256 //--
257 CMICmdBase * CMICmdCmdDataEvaluateExpression::CreateSelf( void )
258 {
259         return new CMICmdCmdDataEvaluateExpression();
260 }
261
262 //++ ------------------------------------------------------------------------------------
263 // Details:     Examine the expression string to see if it contains invalid characters.
264 // Type:        Method.
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.
268 // Throws:      None.
269 //--
270 bool CMICmdCmdDataEvaluateExpression::HaveInvalidCharacterInExpression( const CMIUtilString & vrExpr, MIchar & vrwInvalidChar )
271 {
272         bool bFoundInvalidCharInExpression = false;
273         vrwInvalidChar = 0x00;
274
275         if( vrExpr.at( 0 ) == '\\' )
276         {
277                 // Example: Mouse hover over "%5d" expression has \"%5d\" in it 
278                 bFoundInvalidCharInExpression = true;
279                 vrwInvalidChar = '\\';
280         }
281                 
282         return bFoundInvalidCharInExpression;
283 }
284
285 //---------------------------------------------------------------------------------------
286 //---------------------------------------------------------------------------------------
287 //---------------------------------------------------------------------------------------
288
289 //++ ------------------------------------------------------------------------------------
290 // Details:     CMICmdCmdDataDisassemble constructor.
291 // Type:        Method.
292 // Args:        None.
293 // Return:      None.
294 // Throws:      None.
295 //--
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 )
303 {
304         // Command factory matches this name with that received from the stdin stream
305         m_strMiCmd = "data-disassemble";
306         
307         // Required by the CMICmdFactory when registering *this command
308         m_pSelfCreatorFn = &CMICmdCmdDataDisassemble::CreateSelf;
309 }
310
311 //++ ------------------------------------------------------------------------------------
312 // Details:     CMICmdCmdDataDisassemble destructor.
313 // Type:        Overrideable.
314 // Args:        None.
315 // Return:      None.
316 // Throws:      None.
317 //--
318 CMICmdCmdDataDisassemble::~CMICmdCmdDataDisassemble( void )
319 {
320 }
321
322 //++ ------------------------------------------------------------------------------------
323 // Details:     The invoker requires this function. The parses the command line options 
324 //                      arguments to extract values for each of those arguments.
325 // Type:        Overridden.
326 // Args:        None.
327 // Return:      MIstatus::success - Functional succeeded.
328 //                      MIstatus::failure - Functional failed.
329 // Throws:      None.
330 //--
331 bool CMICmdCmdDataDisassemble::ParseArgs( void )
332 {
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() );
339 }
340
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.
344 // Type:        Overridden.
345 // Args:        None.
346 // Return:      MIstatus::success - Functional succeeded.
347 //                      MIstatus::failure - Functional failed.
348 // Throws:      None.
349 //--
350 bool CMICmdCmdDataDisassemble::Execute( void )
351 {
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 );
356
357         // Retrieve the --thread option's thread ID (only 1)
358         MIuint64 nThreadId = UINT64_MAX;
359         if( !pArgThread->GetExpectedOption< CMICmdArgValNumber, MIuint64 >( nThreadId ) )
360         {
361                 SetError( CMIUtilString::Format( MIRSRC( IDS_CMD_ERR_THREAD_INVALID ), m_cmdData.strMiCmd.c_str(), m_constStrArgThread.c_str() ) );
362                 return MIstatus::failure;
363         }
364         CMIUtilString strAddrStart;
365         if( !pArgAddrStart->GetExpectedOption< CMICmdArgValString, CMIUtilString >( strAddrStart ) )
366         {
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;
369         }
370         MIint64 nAddrStart = 0;
371         if( !strAddrStart.ExtractNumber( nAddrStart ) )
372         {
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;
375         }
376         
377         CMIUtilString strAddrEnd;
378         if( !pArgAddrEnd->GetExpectedOption< CMICmdArgValString, CMIUtilString >( strAddrEnd ) )
379         {
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;
382         }
383         MIint64 nAddrEnd = 0;
384         if( !strAddrEnd.ExtractNumber( nAddrEnd ) )
385         {
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;
388         }
389         const MIuint nDisasmMode = pArgMode->GetValue();
390
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++ )
397         {
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;
409
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 );
423                 
424                 if( nDisasmMode == 1 )
425                 {
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;
430
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 );
443                 }
444                 else
445                 {
446                         m_miValueList.Add( miValueTuple );
447                 }
448         }
449
450         return MIstatus::success;
451 }
452
453 //++ ------------------------------------------------------------------------------------
454 // Details:     The invoker requires this function. The command prepares a MI Record Result
455 //                      for the work carried out in the Execute().
456 // Type:        Overridden.
457 // Args:        None.
458 // Return:      MIstatus::success - Functional succeeded.
459 //                      MIstatus::failure - Functional failed.
460 // Throws:      None.
461 //--
462 bool CMICmdCmdDataDisassemble::Acknowledge( void )
463 {
464         const CMICmnMIValueResult miValueResult( "asm_insns", m_miValueList );
465         const CMICmnMIResultRecord miRecordResult( m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Done, miValueResult );
466         m_miResultRecord = miRecordResult;
467                                 
468         return MIstatus::success;
469 }
470
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.
475 // Args:        None.
476 // Return:      CMICmdBase * - Pointer to a new command.
477 // Throws:      None.
478 //--
479 CMICmdBase * CMICmdCmdDataDisassemble::CreateSelf( void )
480 {
481         return new CMICmdCmdDataDisassemble();
482 }
483
484 //---------------------------------------------------------------------------------------
485 //---------------------------------------------------------------------------------------
486 //---------------------------------------------------------------------------------------
487
488 //++ ------------------------------------------------------------------------------------
489 // Details:     CMICmdCmdDataReadMemoryBytes constructor.
490 // Type:        Method.
491 // Args:        None.
492 // Return:      None.
493 // Throws:      None.
494 //--
495 CMICmdCmdDataReadMemoryBytes::CMICmdCmdDataReadMemoryBytes( void )
496 :       m_constStrArgThread( "thread" )
497 ,       m_constStrArgByteOffset( "o" )  
498 ,       m_constStrArgAddrStart( "address" )     
499 ,       m_constStrArgNumBytes( "count" )        
500 ,       m_pBufferMemory( nullptr )
501 ,       m_nAddrStart( 0 )
502 ,       m_nAddrNumBytesToRead( 0 )
503 ,       m_nAddrOffset( 0 )
504 {
505         // Command factory matches this name with that received from the stdin stream
506         m_strMiCmd = "data-read-memory-bytes";
507         
508         // Required by the CMICmdFactory when registering *this command
509         m_pSelfCreatorFn = &CMICmdCmdDataReadMemoryBytes::CreateSelf;
510 }
511
512 //++ ------------------------------------------------------------------------------------
513 // Details:     CMICmdCmdDataReadMemoryBytes destructor.
514 // Type:        Overrideable.
515 // Args:        None.
516 // Return:      None.
517 // Throws:      None.
518 //--
519 CMICmdCmdDataReadMemoryBytes::~CMICmdCmdDataReadMemoryBytes( void )
520 {
521         if( m_pBufferMemory != nullptr )
522         {
523                 delete [] m_pBufferMemory;
524                 m_pBufferMemory = nullptr;
525         }
526 }
527
528 //++ ------------------------------------------------------------------------------------
529 // Details:     The invoker requires this function. The parses the command line options 
530 //                      arguments to extract values for each of those arguments.
531 // Type:        Overridden.
532 // Args:        None.
533 // Return:      MIstatus::success - Functional succeeded.
534 //                      MIstatus::failure - Functional failed.
535 // Throws:      None.
536 //--
537 bool CMICmdCmdDataReadMemoryBytes::ParseArgs( void )
538 {
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() );
544 }
545
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.
549 // Type:        Overridden.
550 // Args:        None.
551 // Return:      MIstatus::success - Functional succeeded.
552 //                      MIstatus::failure - Functional failed.
553 // Throws:      None.
554 //--
555 bool CMICmdCmdDataReadMemoryBytes::Execute( void )
556 {
557         CMICMDBASE_GETOPTION( pArgAddrStart, Number, m_constStrArgAddrStart );
558         CMICMDBASE_GETOPTION( pArgAddrOffset, Number, m_constStrArgByteOffset );
559         CMICMDBASE_GETOPTION( pArgNumBytes, Number, m_constStrArgNumBytes );
560
561         const MIuint64 nAddrStart = pArgAddrStart->GetValue(); 
562         const MIuint64 nAddrNumBytes = pArgNumBytes->GetValue();
563         if( pArgAddrOffset->GetFound() )
564                 m_nAddrOffset = pArgAddrOffset->GetValue();
565         
566         m_pBufferMemory = new MIuchar[ nAddrNumBytes ];
567         if( m_pBufferMemory == nullptr )
568         {
569                 SetError( CMIUtilString::Format( MIRSRC( IDS_CMD_ERR_MEMORY_ALLOC_FAILURE ), m_cmdData.strMiCmd.c_str(), nAddrNumBytes ) );
570                 return MIstatus::failure;
571         }
572         
573         CMICmnLLDBDebugSessionInfo & rSessionInfo( CMICmnLLDBDebugSessionInfo::Instance() );
574         lldb::SBProcess & rProcess = rSessionInfo.m_lldbProcess;
575         lldb::SBError error;
576         const MIuint64 nReadBytes = rProcess.ReadMemory( static_cast< lldb::addr_t >( nAddrStart ), (void *) m_pBufferMemory, nAddrNumBytes, error );
577         if( nReadBytes != nAddrNumBytes )
578         {
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;
581         }
582         if( error.Fail() )
583         {
584                 lldb::SBStream err;
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;
588         }
589
590         m_nAddrStart = nAddrStart;
591         m_nAddrNumBytesToRead = nAddrNumBytes;
592         
593         return MIstatus::success;
594 }
595
596 //++ ------------------------------------------------------------------------------------
597 // Details:     The invoker requires this function. The command prepares a MI Record Result
598 //                      for the work carried out in the Execute().
599 // Type:        Overridden.
600 // Args:        None.
601 // Return:      MIstatus::success - Functional succeeded.
602 //                      MIstatus::failure - Functional failed.
603 // Throws:      None.
604 //--
605 bool CMICmdCmdDataReadMemoryBytes::Acknowledge( void )
606 {
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 );
617
618         // MI: contents=\" \"
619         CMIUtilString strContent;
620         strContent.reserve( (m_nAddrNumBytesToRead << 1) + 1 );
621         for( MIuint64 i = 0; i < m_nAddrNumBytesToRead; i ++ )
622         {
623                 strContent += CMIUtilString::Format( "%02x", m_pBufferMemory[ i ] );
624         }
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 );
630         
631         const CMICmnMIResultRecord miRecordResult( m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Done, miValueResult5 );
632         m_miResultRecord = miRecordResult;
633                                 
634         return MIstatus::success;
635 }
636
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.
641 // Args:        None.
642 // Return:      CMICmdBase * - Pointer to a new command.
643 // Throws:      None.
644 //--
645 CMICmdBase * CMICmdCmdDataReadMemoryBytes::CreateSelf( void )
646 {
647         return new CMICmdCmdDataReadMemoryBytes();
648 }
649
650 //---------------------------------------------------------------------------------------
651 //---------------------------------------------------------------------------------------
652 //---------------------------------------------------------------------------------------
653
654 //++ ------------------------------------------------------------------------------------
655 // Details:     CMICmdCmdDataReadMemory constructor.
656 // Type:        Method.
657 // Args:        None.
658 // Return:      None.
659 // Throws:      None.
660 //--
661 CMICmdCmdDataReadMemory::CMICmdCmdDataReadMemory( void )
662 {
663         // Command factory matches this name with that received from the stdin stream
664         m_strMiCmd = "data-read-memory";
665         
666         // Required by the CMICmdFactory when registering *this command
667         m_pSelfCreatorFn = &CMICmdCmdDataReadMemory::CreateSelf;
668 }
669
670 //++ ------------------------------------------------------------------------------------
671 // Details:     CMICmdCmdDataReadMemory destructor.
672 // Type:        Overrideable.
673 // Args:        None.
674 // Return:      None.
675 // Throws:      None.
676 //--
677 CMICmdCmdDataReadMemory::~CMICmdCmdDataReadMemory( void )
678 {
679 }
680
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.
684 // Type:        Overridden.
685 // Args:        None.
686 // Return:      MIstatus::success - Functional succeeded.
687 //                      MIstatus::failure - Functional failed.
688 // Throws:      None.
689 //--
690 bool CMICmdCmdDataReadMemory::Execute( void )
691 {
692         // Do nothing - command deprecated use "data-read-memory-bytes" command
693         return MIstatus::success;
694 }
695
696 //++ ------------------------------------------------------------------------------------
697 // Details:     The invoker requires this function. The command prepares a MI Record Result
698 //                      for the work carried out in the Execute().
699 // Type:        Overridden.
700 // Args:        None.
701 // Return:      MIstatus::success - Functional succeeded.
702 //                      MIstatus::failure - Functional failed.
703 // Throws:      None.
704 //--
705 bool CMICmdCmdDataReadMemory::Acknowledge( void )
706 {
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;
712         
713         return MIstatus::success;
714 }
715
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.
720 // Args:        None.
721 // Return:      CMICmdBase * - Pointer to a new command.
722 // Throws:      None.
723 //--
724 CMICmdBase * CMICmdCmdDataReadMemory::CreateSelf( void )
725 {
726         return new CMICmdCmdDataReadMemory();
727 }
728
729 //---------------------------------------------------------------------------------------
730 //---------------------------------------------------------------------------------------
731 //---------------------------------------------------------------------------------------
732
733 //++ ------------------------------------------------------------------------------------
734 // Details:     CMICmdCmdDataListRegisterNames constructor.
735 // Type:        Method.
736 // Args:        None.
737 // Return:      None.
738 // Throws:      None.
739 //--
740 CMICmdCmdDataListRegisterNames::CMICmdCmdDataListRegisterNames( void )
741 :       m_constStrArgThreadGroup( "thread-group" )
742 ,       m_constStrArgRegNo( "regno" )
743 ,       m_miValueList( true )
744 {
745         // Command factory matches this name with that received from the stdin stream
746         m_strMiCmd = "data-list-register-names";
747         
748         // Required by the CMICmdFactory when registering *this command
749         m_pSelfCreatorFn = &CMICmdCmdDataListRegisterNames::CreateSelf;
750 }
751
752 //++ ------------------------------------------------------------------------------------
753 // Details:     CMICmdCmdDataReadMemoryBytes destructor.
754 // Type:        Overrideable.
755 // Args:        None.
756 // Return:      None.
757 // Throws:      None.
758 //--
759 CMICmdCmdDataListRegisterNames::~CMICmdCmdDataListRegisterNames( void )
760 {
761 }
762
763 //++ ------------------------------------------------------------------------------------
764 // Details:     The invoker requires this function. The parses the command line options 
765 //                      arguments to extract values for each of those arguments.
766 // Type:        Overridden.
767 // Args:        None.
768 // Return:      MIstatus::success - Functional succeeded.
769 //                      MIstatus::failure - Functional failed.
770 // Throws:      None.
771 //--
772 bool CMICmdCmdDataListRegisterNames::ParseArgs( void )
773 {
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() );
777 }
778
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.
782 // Type:        Overridden.
783 // Args:        None.
784 // Return:      MIstatus::success - Functional succeeded.
785 //                      MIstatus::failure - Functional failed.
786 // Throws:      None.
787 //--
788 bool CMICmdCmdDataListRegisterNames::Execute( void )
789 {
790         CMICmnLLDBDebugSessionInfo & rSessionInfo( CMICmnLLDBDebugSessionInfo::Instance() );
791         lldb::SBProcess & rProcess = rSessionInfo.m_lldbProcess;
792         if( !rProcess.IsValid() )
793         {
794                 SetError( CMIUtilString::Format( MIRSRC( IDS_CMD_ERR_INVALID_PROCESS ), m_cmdData.strMiCmd.c_str() ) );
795                 return MIstatus::failure;
796         }
797         
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++ )
803         {
804                 lldb::SBValue value = registers.GetValueAtIndex( i );
805                 const MIuint nRegChildren = value.GetNumChildren();
806                 for( MIuint j = 0; j < nRegChildren; j++ )
807                 {
808                         lldb::SBValue value2 = value.GetChildAtIndex( j );
809                         if( value2.IsValid() )
810                         {
811                                 const CMICmnMIValueConst miValueConst( CMICmnLLDBUtilSBValue( value2 ).GetName() );
812                                 m_miValueList.Add( miValueConst );
813                         }
814                 }
815         }
816         
817         return MIstatus::success;
818 }
819
820 //++ ------------------------------------------------------------------------------------
821 // Details:     The invoker requires this function. The command prepares a MI Record Result
822 //                      for the work carried out in the Execute().
823 // Type:        Overridden.
824 // Args:        None.
825 // Return:      MIstatus::success - Functional succeeded.
826 //                      MIstatus::failure - Functional failed.
827 // Throws:      None.
828 //--
829 bool CMICmdCmdDataListRegisterNames::Acknowledge( void )
830 {
831         const CMICmnMIValueResult miValueResult( "register-names", m_miValueList );
832         const CMICmnMIResultRecord miRecordResult( m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Done, miValueResult );
833         m_miResultRecord = miRecordResult;
834         
835         return MIstatus::success;
836 }
837
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.
842 // Args:        None.
843 // Return:      CMICmdBase * - Pointer to a new command.
844 // Throws:      None.
845 //--
846 CMICmdBase * CMICmdCmdDataListRegisterNames::CreateSelf( void )
847 {
848         return new CMICmdCmdDataListRegisterNames();
849 }
850
851 //---------------------------------------------------------------------------------------
852 //---------------------------------------------------------------------------------------
853 //---------------------------------------------------------------------------------------
854
855 //++ ------------------------------------------------------------------------------------
856 // Details:     CMICmdCmdDataListRegisterValues constructor.
857 // Type:        Method.
858 // Args:        None.
859 // Return:      None.
860 // Throws:      None.
861 //--
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 )
869 {
870         // Command factory matches this name with that received from the stdin stream
871         m_strMiCmd = "data-list-register-values";
872         
873         // Required by the CMICmdFactory when registering *this command
874         m_pSelfCreatorFn = &CMICmdCmdDataListRegisterValues::CreateSelf;
875 }
876
877 //++ ------------------------------------------------------------------------------------
878 // Details:     CMICmdCmdDataListRegisterValues destructor.
879 // Type:        Overrideable.
880 // Args:        None.
881 // Return:      None.
882 // Throws:      None.
883 //--
884 CMICmdCmdDataListRegisterValues::~CMICmdCmdDataListRegisterValues( void )
885 {
886 }
887
888 //++ ------------------------------------------------------------------------------------
889 // Details:     The invoker requires this function. The parses the command line options 
890 //                      arguments to extract values for each of those arguments.
891 // Type:        Overridden.
892 // Args:        None.
893 // Return:      MIstatus::success - Functional succeeded.
894 //                      MIstatus::failure - Functional failed.
895 // Throws:      None.
896 //--
897 bool CMICmdCmdDataListRegisterValues::ParseArgs( void )
898 {
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() );
904 }
905
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.
909 // Type:        Overridden.
910 // Args:        None.
911 // Return:      MIstatus::success - Functional succeeded.
912 //                      MIstatus::failure - Functional failed.
913 // Throws:      None.
914 //--
915 bool CMICmdCmdDataListRegisterValues::Execute( void )
916 {
917         CMICMDBASE_GETOPTION( pArgFormat, String, m_constStrArgFormat );
918         CMICMDBASE_GETOPTION( pArgRegNo, ListOfN, m_constStrArgRegNo );
919         
920         const CMIUtilString & rStrFormat( pArgFormat->GetValue() );
921         if( rStrFormat.length() != 1 )
922         {
923                 SetError( CMIUtilString::Format( MIRSRC( IDS_CMD_ERR_INVALID_FORMAT_TYPE ), m_cmdData.strMiCmd.c_str(), rStrFormat.c_str() ) );
924                 return MIstatus::failure;
925         }
926         const CMICmnLLDBDebugSessionInfoVarObj::varFormat_e eFormat = CMICmnLLDBDebugSessionInfoVarObj::GetVarFormatForChar( rStrFormat[ 0 ] );
927         if( eFormat == CMICmnLLDBDebugSessionInfoVarObj::eVarFormat_Invalid )
928         {
929                 SetError( CMIUtilString::Format( MIRSRC( IDS_CMD_ERR_INVALID_FORMAT_TYPE ), m_cmdData.strMiCmd.c_str(), rStrFormat.c_str() ) );
930                 return MIstatus::failure;
931         }
932
933         CMICmnLLDBDebugSessionInfo & rSessionInfo( CMICmnLLDBDebugSessionInfo::Instance() );
934         lldb::SBProcess & rProcess = rSessionInfo.m_lldbProcess;
935         if( !rProcess.IsValid() )
936         {
937                 SetError( CMIUtilString::Format( MIRSRC( IDS_CMD_ERR_INVALID_PROCESS ), m_cmdData.strMiCmd.c_str() ) );
938                 return MIstatus::failure;
939         }
940         m_pProcess = &rProcess;
941
942         const CMICmdArgValListBase::VecArgObjPtr_t & rVecRegNo( pArgRegNo->GetExpectedOptions() );
943         CMICmdArgValListBase::VecArgObjPtr_t::const_iterator it = rVecRegNo.begin();
944         while( it != rVecRegNo.end() )
945         {
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 ) );
950
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 );
958
959                 // Next
960                 ++it;
961         }
962         
963         return MIstatus::success;
964 }
965
966 //++ ------------------------------------------------------------------------------------
967 // Details:     The invoker requires this function. The command prepares a MI Record Result
968 //                      for the work carried out in the Execute().
969 // Type:        Overridden.
970 // Args:        None.
971 // Return:      MIstatus::success - Functional succeeded.
972 //                      MIstatus::failure - Functional failed.
973 // Throws:      None.
974 //--
975 bool CMICmdCmdDataListRegisterValues::Acknowledge( void )
976 {
977         const CMICmnMIValueResult miValueResult( "register-values", m_miValueList );
978         const CMICmnMIResultRecord miRecordResult( m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Done, miValueResult );
979         m_miResultRecord = miRecordResult;
980                                 
981         return MIstatus::success;
982 }
983
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.
988 // Args:        None.
989 // Return:      CMICmdBase * - Pointer to a new command.
990 // Throws:      None.
991 //--
992 CMICmdBase * CMICmdCmdDataListRegisterValues::CreateSelf( void )
993 {
994         return new CMICmdCmdDataListRegisterValues();
995 }
996
997 //++ ------------------------------------------------------------------------------------
998 // Details:     Required by the CMICmdFactory when registering *this command. The factory
999 //                      calls this function to create an instance of *this command.
1000 // Type:        Method.
1001 // Args:        None.
1002 // Return:      lldb::SBValue - LLDB SBValue object.
1003 // Throws:      None.
1004 //--
1005 lldb::SBValue CMICmdCmdDataListRegisterValues::GetRegister( const MIuint vRegisterIndex ) const
1006 {
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++ )
1012         {
1013                 lldb::SBValue value = registers.GetValueAtIndex( i );
1014                 const MIuint nRegChildren = value.GetNumChildren();
1015                 if( nRegChildren > 0 )
1016                 {
1017                         lldb::SBValue value2 = value.GetChildAtIndex( vRegisterIndex );
1018                         if( value2.IsValid() )
1019                         {
1020                                 return value2;
1021                         }
1022                 }
1023         }
1024
1025         return lldb::SBValue();
1026 }
1027
1028 //---------------------------------------------------------------------------------------
1029 //---------------------------------------------------------------------------------------
1030 //---------------------------------------------------------------------------------------
1031
1032 //++ ------------------------------------------------------------------------------------
1033 // Details:     CMICmdCmdDataListRegisterChanged constructor.
1034 // Type:        Method.
1035 // Args:        None.
1036 // Return:      None.
1037 // Throws:      None.
1038 //--
1039 CMICmdCmdDataListRegisterChanged::CMICmdCmdDataListRegisterChanged( void )
1040 {
1041         // Command factory matches this name with that received from the stdin stream
1042         m_strMiCmd = "data-list-changed-registers";
1043         
1044         // Required by the CMICmdFactory when registering *this command
1045         m_pSelfCreatorFn = &CMICmdCmdDataListRegisterChanged::CreateSelf;
1046 }
1047
1048 //++ ------------------------------------------------------------------------------------
1049 // Details:     CMICmdCmdDataListRegisterChanged destructor.
1050 // Type:        Overrideable.
1051 // Args:        None.
1052 // Return:      None.
1053 // Throws:      None.
1054 //--
1055 CMICmdCmdDataListRegisterChanged::~CMICmdCmdDataListRegisterChanged( void )
1056 {
1057 }
1058
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.
1063 // Args:        None.
1064 // Return:      MIstatus::success - Functional succeeded.
1065 //                      MIstatus::failure - Functional failed.
1066 // Throws:      None.
1067 //--
1068 bool CMICmdCmdDataListRegisterChanged::Execute( void )
1069 {
1070         // Do nothing
1071         
1072         return MIstatus::success;
1073 }
1074
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.
1079 // Args:        None.
1080 // Return:      MIstatus::success - Functional succeeded.
1081 //                      MIstatus::failure - Functional failed.
1082 // Throws:      None.
1083 //--
1084 bool CMICmdCmdDataListRegisterChanged::Acknowledge( void )
1085 {
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;
1090
1091         return MIstatus::success;
1092 }
1093
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.
1098 // Args:        None.
1099 // Return:      CMICmdBase * - Pointer to a new command.
1100 // Throws:      None.
1101 //--
1102 CMICmdBase * CMICmdCmdDataListRegisterChanged::CreateSelf( void )
1103 {
1104         return new CMICmdCmdDataListRegisterChanged();
1105 }
1106
1107 //---------------------------------------------------------------------------------------
1108 //---------------------------------------------------------------------------------------
1109 //---------------------------------------------------------------------------------------
1110
1111 //++ ------------------------------------------------------------------------------------
1112 // Details:     CMICmdCmdDataWriteMemoryBytes constructor.
1113 // Type:        Method.
1114 // Args:        None.
1115 // Return:      None.
1116 // Throws:      None.
1117 //--
1118 CMICmdCmdDataWriteMemoryBytes::CMICmdCmdDataWriteMemoryBytes( void )
1119 :       m_constStrArgThread( "thread" )
1120 ,       m_constStrArgAddr( "address" )  
1121 ,       m_constStrArgContents( "contents" )     
1122 ,       m_constStrArgCount( "count" )   
1123 ,       m_nAddr( 0 )
1124 ,       m_nCount( 0 )
1125 {
1126         // Command factory matches this name with that received from the stdin stream
1127         m_strMiCmd = "data-write-memory-bytes";
1128         
1129         // Required by the CMICmdFactory when registering *this command
1130         m_pSelfCreatorFn = &CMICmdCmdDataWriteMemoryBytes::CreateSelf;
1131 }
1132
1133 //++ ------------------------------------------------------------------------------------
1134 // Details:     CMICmdCmdDataWriteMemoryBytes destructor.
1135 // Type:        Overrideable.
1136 // Args:        None.
1137 // Return:      None.
1138 // Throws:      None.
1139 //--
1140 CMICmdCmdDataWriteMemoryBytes::~CMICmdCmdDataWriteMemoryBytes( void )
1141 {
1142 }
1143
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.
1148 // Args:        None.
1149 // Return:      MIstatus::success - Functional succeeded.
1150 //                      MIstatus::failure - Functional failed.
1151 // Throws:      None.
1152 //--
1153 bool CMICmdCmdDataWriteMemoryBytes::ParseArgs( void )
1154 {
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() );
1160 }
1161
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.
1166 // Args:        None.
1167 // Return:      MIstatus::success - Functional succeeded.
1168 //                      MIstatus::failure - Functional failed.
1169 // Throws:      None.
1170 //--
1171 bool CMICmdCmdDataWriteMemoryBytes::Execute( void )
1172 {
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 );
1178         // 
1179         // Numbers extracts as string types as they could be hex numbers
1180         // '&' is not recognised and so has to be removed
1181
1182         return MIstatus::success;
1183 }
1184
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.
1189 // Args:        None.
1190 // Return:      MIstatus::success - Functional succeeded.
1191 //                      MIstatus::failure - Functional failed.
1192 // Throws:      None.
1193 //--
1194 bool CMICmdCmdDataWriteMemoryBytes::Acknowledge( void )
1195 {
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;
1200
1201         return MIstatus::success;
1202 }
1203
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.
1208 // Args:        None.
1209 // Return:      CMICmdBase * - Pointer to a new command.
1210 // Throws:      None.
1211 //--
1212 CMICmdBase * CMICmdCmdDataWriteMemoryBytes::CreateSelf( void )
1213 {
1214         return new CMICmdCmdDataWriteMemoryBytes();
1215 }
1216
1217 //---------------------------------------------------------------------------------------
1218 //---------------------------------------------------------------------------------------
1219 //---------------------------------------------------------------------------------------
1220
1221 //++ ------------------------------------------------------------------------------------
1222 // Details:     CMICmdCmdDataWriteMemory constructor.
1223 // Type:        Method.
1224 // Args:        None.
1225 // Return:      None.
1226 // Throws:      None.
1227 //--
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" )     
1235 ,       m_nAddr( 0 )
1236 ,       m_nCount( 0 )
1237 ,       m_pBufferMemory( nullptr )      
1238 {
1239         // Command factory matches this name with that received from the stdin stream
1240         m_strMiCmd = "data-write-memory";
1241         
1242         // Required by the CMICmdFactory when registering *this command
1243         m_pSelfCreatorFn = &CMICmdCmdDataWriteMemory::CreateSelf;
1244 }
1245
1246 //++ ------------------------------------------------------------------------------------
1247 // Details:     CMICmdCmdDataWriteMemory destructor.
1248 // Type:        Overrideable.
1249 // Args:        None.
1250 // Return:      None.
1251 // Throws:      None.
1252 //--
1253 CMICmdCmdDataWriteMemory::~CMICmdCmdDataWriteMemory( void )
1254 {
1255         if( m_pBufferMemory != nullptr )
1256         {
1257                 delete [] m_pBufferMemory;
1258                 m_pBufferMemory = nullptr;
1259         }
1260 }
1261
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.
1266 // Args:        None.
1267 // Return:      MIstatus::success - Functional succeeded.
1268 //                      MIstatus::failure - Functional failed.
1269 // Throws:      None.
1270 //--
1271 bool CMICmdCmdDataWriteMemory::ParseArgs( void )
1272 {
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() );
1280 }
1281
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.
1286 // Args:        None.
1287 // Return:      MIstatus::success - Functional succeeded.
1288 //                      MIstatus::failure - Functional failed.
1289 // Throws:      None.
1290 //--
1291 bool CMICmdCmdDataWriteMemory::Execute( void )
1292 {
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 );
1297
1298         MIuint nAddrOffset = 0;
1299         if( pArgOffset->GetFound() && !pArgOffset->GetExpectedOption< CMICmdArgValNumber, MIuint>( nAddrOffset ) )
1300         {
1301                 SetError( CMIUtilString::Format( MIRSRC( IDS_CMD_ARGS_ERR_VALIDATION_INVALID ), m_cmdData.strMiCmd.c_str(), m_constStrArgAddr.c_str() ) );
1302                 return MIstatus::failure;
1303         }
1304         m_nAddr = pArgAddr->GetValue();
1305         m_nCount = pArgNumber->GetValue();
1306         const MIuint64 nValue = pArgContents->GetValue();
1307
1308         m_pBufferMemory = new MIuchar [ m_nCount ];
1309         if( m_pBufferMemory == nullptr )
1310         {
1311                 SetError( CMIUtilString::Format( MIRSRC( IDS_CMD_ERR_MEMORY_ALLOC_FAILURE ), m_cmdData.strMiCmd.c_str(), m_nCount ) );
1312                 return MIstatus::failure;
1313         }
1314         *m_pBufferMemory = static_cast< MIchar >( nValue );
1315
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 ) )
1322         {
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;
1325         }
1326         if( error.Fail() )
1327         {
1328                 lldb::SBStream err;
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;
1332         }
1333         
1334         return MIstatus::success;
1335 }
1336
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.
1341 // Args:        None.
1342 // Return:      MIstatus::success - Functional succeeded.
1343 //                      MIstatus::failure - Functional failed.
1344 // Throws:      None.
1345 //--
1346 bool CMICmdCmdDataWriteMemory::Acknowledge( void )
1347 {
1348         const CMICmnMIResultRecord miRecordResult( m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Done );
1349         m_miResultRecord = miRecordResult;
1350
1351         return MIstatus::success;
1352 }
1353
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.
1358 // Args:        None.
1359 // Return:      CMICmdBase * - Pointer to a new command.
1360 // Throws:      None.
1361 //--
1362 CMICmdBase * CMICmdCmdDataWriteMemory::CreateSelf( void )
1363 {
1364         return new CMICmdCmdDataWriteMemory();
1365 }