]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/llvm/tools/lldb/tools/lldb-mi/MICmdCmdData.cpp
Merge llvm, clang, lld, lldb, compiler-rt and libc++ r306325, and update
[FreeBSD/FreeBSD.git] / contrib / llvm / tools / lldb / 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 // Overview:    CMICmdCmdDataEvaluateExpression     implementation.
11 //              CMICmdCmdDataDisassemble            implementation.
12 //              CMICmdCmdDataReadMemoryBytes        implementation.
13 //              CMICmdCmdDataReadMemory             implementation.
14 //              CMICmdCmdDataListRegisterNames      implementation.
15 //              CMICmdCmdDataListRegisterValues     implementation.
16 //              CMICmdCmdDataListRegisterChanged    implementation.
17 //              CMICmdCmdDataWriteMemoryBytes       implementation.
18 //              CMICmdCmdDataWriteMemory            implementation.
19 //              CMICmdCmdDataInfoLine               implementation.
20
21 // Third Party Headers:
22 #include "lldb/API/SBCommandInterpreter.h"
23 #include "lldb/API/SBInstruction.h"
24 #include "lldb/API/SBInstructionList.h"
25 #include "lldb/API/SBStream.h"
26 #include "lldb/API/SBThread.h"
27 #include "llvm/ADT/SmallVector.h"
28 #include "llvm/ADT/StringRef.h"
29 #include "llvm/Support/Regex.h"
30 #include <inttypes.h> // For PRIx64
31
32 // In-house headers:
33 #include "MICmdArgValConsume.h"
34 #include "MICmdArgValListOfN.h"
35 #include "MICmdArgValNumber.h"
36 #include "MICmdArgValOptionLong.h"
37 #include "MICmdArgValOptionShort.h"
38 #include "MICmdArgValString.h"
39 #include "MICmdArgValThreadGrp.h"
40 #include "MICmdCmdData.h"
41 #include "MICmnLLDBDebugSessionInfo.h"
42 #include "MICmnLLDBDebugSessionInfoVarObj.h"
43 #include "MICmnLLDBDebugger.h"
44 #include "MICmnLLDBProxySBValue.h"
45 #include "MICmnLLDBUtilSBValue.h"
46 #include "MICmnMIResultRecord.h"
47 #include "MICmnMIValueConst.h"
48
49 //++
50 //------------------------------------------------------------------------------------
51 // Details: CMICmdCmdDataEvaluateExpression constructor.
52 // Type:    Method.
53 // Args:    None.
54 // Return:  None.
55 // Throws:  None.
56 //--
57 CMICmdCmdDataEvaluateExpression::CMICmdCmdDataEvaluateExpression()
58     : m_bExpressionValid(true), m_bEvaluatedExpression(true), m_strValue("??"),
59       m_bFoundInvalidChar(false), m_cExpressionInvalidChar(0x00),
60       m_constStrArgExpr("expr") {
61   // Command factory matches this name with that received from the stdin stream
62   m_strMiCmd = "data-evaluate-expression";
63
64   // Required by the CMICmdFactory when registering *this command
65   m_pSelfCreatorFn = &CMICmdCmdDataEvaluateExpression::CreateSelf;
66 }
67
68 //++
69 //------------------------------------------------------------------------------------
70 // Details: CMICmdCmdDataEvaluateExpression destructor.
71 // Type:    Overrideable.
72 // Args:    None.
73 // Return:  None.
74 // Throws:  None.
75 //--
76 CMICmdCmdDataEvaluateExpression::~CMICmdCmdDataEvaluateExpression() {}
77
78 //++
79 //------------------------------------------------------------------------------------
80 // Details: The invoker requires this function. The parses the command line
81 // options
82 //          arguments to extract values for each of those arguments.
83 // Type:    Overridden.
84 // Args:    None.
85 // Return:  MIstatus::success - Functional succeeded.
86 //          MIstatus::failure - Functional failed.
87 // Throws:  None.
88 //--
89 bool CMICmdCmdDataEvaluateExpression::ParseArgs() {
90   m_setCmdArgs.Add(
91       new CMICmdArgValString(m_constStrArgExpr, true, true, true, true));
92   return ParseValidateCmdOptions();
93 }
94
95 //++
96 //------------------------------------------------------------------------------------
97 // Details: The invoker requires this function. The command does work in this
98 // function.
99 //          The command is likely to communicate with the LLDB SBDebugger in
100 //          here.
101 // Type:    Overridden.
102 // Args:    None.
103 // Return:  MIstatus::success - Functional succeeded.
104 //          MIstatus::failure - Functional failed.
105 // Throws:  None.
106 //--
107 bool CMICmdCmdDataEvaluateExpression::Execute() {
108   CMICMDBASE_GETOPTION(pArgExpr, String, m_constStrArgExpr);
109
110   const CMIUtilString &rExpression(pArgExpr->GetValue());
111   CMICmnLLDBDebugSessionInfo &rSessionInfo(
112       CMICmnLLDBDebugSessionInfo::Instance());
113   lldb::SBProcess sbProcess = rSessionInfo.GetProcess();
114   lldb::SBThread thread = sbProcess.GetSelectedThread();
115   m_bExpressionValid = (thread.GetNumFrames() > 0);
116   if (!m_bExpressionValid)
117     return MIstatus::success;
118
119   lldb::SBFrame frame = thread.GetSelectedFrame();
120   lldb::SBValue value = frame.EvaluateExpression(rExpression.c_str());
121   m_Error = value.GetError();
122   if (!value.IsValid() || m_Error.Fail())
123     value = frame.FindVariable(rExpression.c_str());
124   const CMICmnLLDBUtilSBValue utilValue(value, true);
125   if (!utilValue.IsValid() || utilValue.IsValueUnknown()) {
126     m_bEvaluatedExpression = false;
127     return MIstatus::success;
128   }
129   if (!utilValue.HasName()) {
130     if (HaveInvalidCharacterInExpression(rExpression,
131                                          m_cExpressionInvalidChar)) {
132       m_bFoundInvalidChar = true;
133       return MIstatus::success;
134     }
135
136     m_strValue = rExpression;
137     return MIstatus::success;
138   }
139   if (rExpression.IsQuoted()) {
140     m_strValue = rExpression.Trim('\"');
141     return MIstatus::success;
142   }
143   m_strValue = utilValue.GetValue(true).Escape().AddSlashes();
144   return MIstatus::success;
145 }
146
147 //++
148 //------------------------------------------------------------------------------------
149 // Details: The invoker requires this function. The command prepares a MI Record
150 // Result
151 //          for the work carried out in the Execute().
152 // Type:    Overridden.
153 // Args:    None.
154 // Return:  MIstatus::success - Functional succeeded.
155 //          MIstatus::failure - Functional failed.
156 // Throws:  None.
157 //--
158 bool CMICmdCmdDataEvaluateExpression::Acknowledge() {
159   if (m_bExpressionValid) {
160     if (m_bEvaluatedExpression) {
161       if (m_bFoundInvalidChar) {
162         const CMICmnMIValueConst miValueConst(CMIUtilString::Format(
163             "Invalid character '%c' in expression", m_cExpressionInvalidChar));
164         const CMICmnMIValueResult miValueResult("msg", miValueConst);
165         const CMICmnMIResultRecord miRecordResult(
166             m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Error,
167             miValueResult);
168         m_miResultRecord = miRecordResult;
169         return MIstatus::success;
170       }
171
172       const CMICmnMIValueConst miValueConst(m_strValue);
173       const CMICmnMIValueResult miValueResult("value", miValueConst);
174       const CMICmnMIResultRecord miRecordResult(
175           m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Done,
176           miValueResult);
177       m_miResultRecord = miRecordResult;
178       return MIstatus::success;
179     }
180     CMIUtilString mi_error_msg = "Could not evaluate expression";
181     if (const char *err_msg = m_Error.GetCString())
182       mi_error_msg = err_msg;
183     const CMICmnMIValueConst miValueConst(mi_error_msg.Escape(true));
184     const CMICmnMIValueResult miValueResult("msg", miValueConst);
185     const CMICmnMIResultRecord miRecordResult(
186         m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Error,
187         miValueResult);
188     m_miResultRecord = miRecordResult;
189     return MIstatus::success;
190   }
191
192   const CMICmnMIValueConst miValueConst("Invalid expression");
193   const CMICmnMIValueResult miValueResult("msg", miValueConst);
194   const CMICmnMIResultRecord miRecordResult(
195       m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Error,
196       miValueResult);
197   m_miResultRecord = miRecordResult;
198
199   return MIstatus::success;
200 }
201
202 //++
203 //------------------------------------------------------------------------------------
204 // Details: Required by the CMICmdFactory when registering *this command. The
205 // factory
206 //          calls this function to create an instance of *this command.
207 // Type:    Static method.
208 // Args:    None.
209 // Return:  CMICmdBase * - Pointer to a new command.
210 // Throws:  None.
211 //--
212 CMICmdBase *CMICmdCmdDataEvaluateExpression::CreateSelf() {
213   return new CMICmdCmdDataEvaluateExpression();
214 }
215
216 //++
217 //------------------------------------------------------------------------------------
218 // Details: Examine the expression string to see if it contains invalid
219 // characters.
220 // Type:    Method.
221 // Args:    vrExpr          - (R) Expression string given to *this command.
222 //          vrwInvalidChar  - (W) True = Invalid character found, false =
223 //          nothing found.
224 // Return:  bool - True = Invalid character found, false = nothing found.
225 // Throws:  None.
226 //--
227 bool CMICmdCmdDataEvaluateExpression::HaveInvalidCharacterInExpression(
228     const CMIUtilString &vrExpr, char &vrwInvalidChar) {
229   static const std::string strInvalidCharacters(";#\\");
230   const size_t nInvalidCharacterOffset =
231       vrExpr.find_first_of(strInvalidCharacters);
232   const bool bFoundInvalidCharInExpression =
233       (nInvalidCharacterOffset != CMIUtilString::npos);
234   vrwInvalidChar =
235       bFoundInvalidCharInExpression ? vrExpr[nInvalidCharacterOffset] : 0x00;
236   return bFoundInvalidCharInExpression;
237 }
238
239 //---------------------------------------------------------------------------------------
240 //---------------------------------------------------------------------------------------
241 //---------------------------------------------------------------------------------------
242
243 //++
244 //------------------------------------------------------------------------------------
245 // Details: CMICmdCmdDataDisassemble constructor.
246 // Type:    Method.
247 // Args:    None.
248 // Return:  None.
249 // Throws:  None.
250 //--
251 CMICmdCmdDataDisassemble::CMICmdCmdDataDisassemble()
252     : m_constStrArgAddrStart("s"), m_constStrArgAddrEnd("e"),
253       m_constStrArgMode("mode"), m_miValueList(true) {
254   // Command factory matches this name with that received from the stdin stream
255   m_strMiCmd = "data-disassemble";
256
257   // Required by the CMICmdFactory when registering *this command
258   m_pSelfCreatorFn = &CMICmdCmdDataDisassemble::CreateSelf;
259 }
260
261 //++
262 //------------------------------------------------------------------------------------
263 // Details: CMICmdCmdDataDisassemble destructor.
264 // Type:    Overrideable.
265 // Args:    None.
266 // Return:  None.
267 // Throws:  None.
268 //--
269 CMICmdCmdDataDisassemble::~CMICmdCmdDataDisassemble() {}
270
271 //++
272 //------------------------------------------------------------------------------------
273 // Details: The invoker requires this function. The parses the command line
274 // options
275 //          arguments to extract values for each of those arguments.
276 // Type:    Overridden.
277 // Args:    None.
278 // Return:  MIstatus::success - Functional succeeded.
279 //          MIstatus::failure - Functional failed.
280 // Throws:  None.
281 //--
282 bool CMICmdCmdDataDisassemble::ParseArgs() {
283   m_setCmdArgs.Add(new CMICmdArgValOptionShort(
284       m_constStrArgAddrStart, true, true,
285       CMICmdArgValListBase::eArgValType_StringQuotedNumber, 1));
286   m_setCmdArgs.Add(new CMICmdArgValOptionShort(
287       m_constStrArgAddrEnd, true, true,
288       CMICmdArgValListBase::eArgValType_StringQuotedNumber, 1));
289   m_setCmdArgs.Add(new CMICmdArgValNumber(m_constStrArgMode, true, true));
290   return ParseValidateCmdOptions();
291 }
292
293 //++
294 //------------------------------------------------------------------------------------
295 // Details: The invoker requires this function. The command does work in this
296 // function.
297 //          The command is likely to communicate with the LLDB SBDebugger in
298 //          here.
299 // Type:    Overridden.
300 // Args:    None.
301 // Return:  MIstatus::success - Functional succeeded.
302 //          MIstatus::failure - Functional failed.
303 // Throws:  None.
304 //--
305 bool CMICmdCmdDataDisassemble::Execute() {
306   CMICMDBASE_GETOPTION(pArgThread, OptionLong, m_constStrArgThread);
307   CMICMDBASE_GETOPTION(pArgAddrStart, OptionShort, m_constStrArgAddrStart);
308   CMICMDBASE_GETOPTION(pArgAddrEnd, OptionShort, m_constStrArgAddrEnd);
309   CMICMDBASE_GETOPTION(pArgMode, Number, m_constStrArgMode);
310
311   // Retrieve the --thread option's thread ID (only 1)
312   MIuint64 nThreadId = UINT64_MAX;
313   if (pArgThread->GetFound() &&
314       !pArgThread->GetExpectedOption<CMICmdArgValNumber, MIuint64>(nThreadId)) {
315     SetError(CMIUtilString::Format(MIRSRC(IDS_CMD_ERR_THREAD_INVALID),
316                                    m_cmdData.strMiCmd.c_str(),
317                                    m_constStrArgThread.c_str()));
318     return MIstatus::failure;
319   }
320   CMIUtilString strAddrStart;
321   if (!pArgAddrStart->GetExpectedOption<CMICmdArgValString, CMIUtilString>(
322           strAddrStart)) {
323     SetError(CMIUtilString::Format(
324         MIRSRC(IDS_CMD_ERR_DISASM_ADDR_START_INVALID),
325         m_cmdData.strMiCmd.c_str(), m_constStrArgAddrStart.c_str()));
326     return MIstatus::failure;
327   }
328   MIint64 nAddrStart = 0;
329   if (!strAddrStart.ExtractNumber(nAddrStart)) {
330     SetError(CMIUtilString::Format(
331         MIRSRC(IDS_CMD_ERR_DISASM_ADDR_START_INVALID),
332         m_cmdData.strMiCmd.c_str(), m_constStrArgAddrStart.c_str()));
333     return MIstatus::failure;
334   }
335
336   CMIUtilString strAddrEnd;
337   if (!pArgAddrEnd->GetExpectedOption<CMICmdArgValString, CMIUtilString>(
338           strAddrEnd)) {
339     SetError(CMIUtilString::Format(MIRSRC(IDS_CMD_ERR_DISASM_ADDR_END_INVALID),
340                                    m_cmdData.strMiCmd.c_str(),
341                                    m_constStrArgAddrEnd.c_str()));
342     return MIstatus::failure;
343   }
344   MIint64 nAddrEnd = 0;
345   if (!strAddrEnd.ExtractNumber(nAddrEnd)) {
346     SetError(CMIUtilString::Format(MIRSRC(IDS_CMD_ERR_DISASM_ADDR_END_INVALID),
347                                    m_cmdData.strMiCmd.c_str(),
348                                    m_constStrArgAddrEnd.c_str()));
349     return MIstatus::failure;
350   }
351   const MIuint nDisasmMode = pArgMode->GetValue();
352
353   CMICmnLLDBDebugSessionInfo &rSessionInfo(
354       CMICmnLLDBDebugSessionInfo::Instance());
355   lldb::SBTarget sbTarget = rSessionInfo.GetTarget();
356   lldb::addr_t lldbStartAddr = static_cast<lldb::addr_t>(nAddrStart);
357   lldb::SBInstructionList instructions = sbTarget.ReadInstructions(
358       lldb::SBAddress(lldbStartAddr, sbTarget), nAddrEnd - nAddrStart);
359   const MIuint nInstructions = instructions.GetSize();
360   // Calculate the offset of first instruction so that we can generate offset
361   // starting at 0
362   lldb::addr_t start_offset = 0;
363   if (nInstructions > 0)
364     start_offset =
365         instructions.GetInstructionAtIndex(0).GetAddress().GetOffset();
366
367   for (size_t i = 0; i < nInstructions; i++) {
368     const char *pUnknown = "??";
369     lldb::SBInstruction instrt = instructions.GetInstructionAtIndex(i);
370     const char *pStrMnemonic = instrt.GetMnemonic(sbTarget);
371     pStrMnemonic = (pStrMnemonic != nullptr) ? pStrMnemonic : pUnknown;
372     const char *pStrComment = instrt.GetComment(sbTarget);
373     CMIUtilString strComment;
374     if (pStrComment != nullptr && *pStrComment != '\0')
375       strComment = CMIUtilString::Format("; %s", pStrComment);
376     lldb::SBAddress address = instrt.GetAddress();
377     lldb::addr_t addr = address.GetLoadAddress(sbTarget);
378     const char *pFnName = address.GetFunction().GetName();
379     pFnName = (pFnName != nullptr) ? pFnName : pUnknown;
380     lldb::addr_t addrOffSet = address.GetOffset() - start_offset;
381     const char *pStrOperands = instrt.GetOperands(sbTarget);
382     pStrOperands = (pStrOperands != nullptr) ? pStrOperands : pUnknown;
383     const size_t instrtSize = instrt.GetByteSize();
384
385     // MI "{address=\"0x%016" PRIx64
386     // "\",func-name=\"%s\",offset=\"%lld\",inst=\"%s %s\"}"
387     const CMICmnMIValueConst miValueConst(
388         CMIUtilString::Format("0x%016" PRIx64, addr));
389     const CMICmnMIValueResult miValueResult("address", miValueConst);
390     CMICmnMIValueTuple miValueTuple(miValueResult);
391     const CMICmnMIValueConst miValueConst2(pFnName);
392     const CMICmnMIValueResult miValueResult2("func-name", miValueConst2);
393     miValueTuple.Add(miValueResult2);
394     const CMICmnMIValueConst miValueConst3(
395         CMIUtilString::Format("%lld", addrOffSet));
396     const CMICmnMIValueResult miValueResult3("offset", miValueConst3);
397     miValueTuple.Add(miValueResult3);
398     const CMICmnMIValueConst miValueConst4(
399         CMIUtilString::Format("%d", instrtSize));
400     const CMICmnMIValueResult miValueResult4("size", miValueConst4);
401     miValueTuple.Add(miValueResult4);
402     const CMICmnMIValueConst miValueConst5(
403         CMIUtilString::Format("%s %s%s", pStrMnemonic, pStrOperands,
404                               strComment.Escape(true).c_str()));
405     const CMICmnMIValueResult miValueResult5("inst", miValueConst5);
406     miValueTuple.Add(miValueResult5);
407
408     if (nDisasmMode == 1) {
409       lldb::SBLineEntry lineEntry = address.GetLineEntry();
410       const MIuint nLine = lineEntry.GetLine();
411       const char *pFileName = lineEntry.GetFileSpec().GetFilename();
412       pFileName = (pFileName != nullptr) ? pFileName : pUnknown;
413
414       // MI "src_and_asm_line={line=\"%u\",file=\"%s\",line_asm_insn=[ ]}"
415       const CMICmnMIValueConst miValueConst(
416           CMIUtilString::Format("0x%u", nLine));
417       const CMICmnMIValueResult miValueResult("line", miValueConst);
418       CMICmnMIValueTuple miValueTuple2(miValueResult);
419       const CMICmnMIValueConst miValueConst2(pFileName);
420       const CMICmnMIValueResult miValueResult2("file", miValueConst2);
421       miValueTuple2.Add(miValueResult2);
422       const CMICmnMIValueList miValueList(miValueTuple);
423       const CMICmnMIValueResult miValueResult3("line_asm_insn", miValueList);
424       miValueTuple2.Add(miValueResult3);
425       const CMICmnMIValueResult miValueResult4("src_and_asm_line",
426                                                miValueTuple2);
427       m_miValueList.Add(miValueResult4);
428     } else {
429       m_miValueList.Add(miValueTuple);
430     }
431   }
432
433   return MIstatus::success;
434 }
435
436 //++
437 //------------------------------------------------------------------------------------
438 // Details: The invoker requires this function. The command prepares a MI Record
439 // Result
440 //          for the work carried out in the Execute().
441 // Type:    Overridden.
442 // Args:    None.
443 // Return:  MIstatus::success - Functional succeeded.
444 //          MIstatus::failure - Functional failed.
445 // Throws:  None.
446 //--
447 bool CMICmdCmdDataDisassemble::Acknowledge() {
448   const CMICmnMIValueResult miValueResult("asm_insns", m_miValueList);
449   const CMICmnMIResultRecord miRecordResult(
450       m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Done,
451       miValueResult);
452   m_miResultRecord = miRecordResult;
453
454   return MIstatus::success;
455 }
456
457 //++
458 //------------------------------------------------------------------------------------
459 // Details: Required by the CMICmdFactory when registering *this command. The
460 // factory
461 //          calls this function to create an instance of *this command.
462 // Type:    Static method.
463 // Args:    None.
464 // Return:  CMICmdBase * - Pointer to a new command.
465 // Throws:  None.
466 //--
467 CMICmdBase *CMICmdCmdDataDisassemble::CreateSelf() {
468   return new CMICmdCmdDataDisassemble();
469 }
470
471 //---------------------------------------------------------------------------------------
472 //---------------------------------------------------------------------------------------
473 //---------------------------------------------------------------------------------------
474
475 //++
476 //------------------------------------------------------------------------------------
477 // Details: CMICmdCmdDataReadMemoryBytes constructor.
478 // Type:    Method.
479 // Args:    None.
480 // Return:  None.
481 // Throws:  None.
482 //--
483 CMICmdCmdDataReadMemoryBytes::CMICmdCmdDataReadMemoryBytes()
484     : m_constStrArgByteOffset("o"), m_constStrArgAddrExpr("address"),
485       m_constStrArgNumBytes("count"), m_pBufferMemory(nullptr), m_nAddrStart(0),
486       m_nAddrNumBytesToRead(0) {
487   // Command factory matches this name with that received from the stdin stream
488   m_strMiCmd = "data-read-memory-bytes";
489
490   // Required by the CMICmdFactory when registering *this command
491   m_pSelfCreatorFn = &CMICmdCmdDataReadMemoryBytes::CreateSelf;
492 }
493
494 //++
495 //------------------------------------------------------------------------------------
496 // Details: CMICmdCmdDataReadMemoryBytes destructor.
497 // Type:    Overrideable.
498 // Args:    None.
499 // Return:  None.
500 // Throws:  None.
501 //--
502 CMICmdCmdDataReadMemoryBytes::~CMICmdCmdDataReadMemoryBytes() {
503   if (m_pBufferMemory != nullptr) {
504     delete[] m_pBufferMemory;
505     m_pBufferMemory = nullptr;
506   }
507 }
508
509 //++
510 //------------------------------------------------------------------------------------
511 // Details: The invoker requires this function. The parses the command line
512 // options
513 //          arguments to extract values for each of those arguments.
514 // Type:    Overridden.
515 // Args:    None.
516 // Return:  MIstatus::success - Functional succeeded.
517 //          MIstatus::failure - Functional failed.
518 // Throws:  None.
519 //--
520 bool CMICmdCmdDataReadMemoryBytes::ParseArgs() {
521   m_setCmdArgs.Add(
522       new CMICmdArgValOptionShort(m_constStrArgByteOffset, false, true,
523                                   CMICmdArgValListBase::eArgValType_Number, 1));
524   m_setCmdArgs.Add(
525       new CMICmdArgValString(m_constStrArgAddrExpr, true, true, true, true));
526   m_setCmdArgs.Add(new CMICmdArgValNumber(m_constStrArgNumBytes, true, true));
527   return ParseValidateCmdOptions();
528 }
529
530 //++
531 //------------------------------------------------------------------------------------
532 // Details: The invoker requires this function. The command does work in this
533 // function.
534 //          The command is likely to communicate with the LLDB SBDebugger in
535 //          here.
536 // Type:    Overridden.
537 // Args:    None.
538 // Return:  MIstatus::success - Function succeeded.
539 //          MIstatus::failure - Function failed.
540 // Throws:  None.
541 //--
542 bool CMICmdCmdDataReadMemoryBytes::Execute() {
543   CMICMDBASE_GETOPTION(pArgThread, OptionLong, m_constStrArgThread);
544   CMICMDBASE_GETOPTION(pArgFrame, OptionLong, m_constStrArgFrame);
545   CMICMDBASE_GETOPTION(pArgAddrOffset, OptionShort, m_constStrArgByteOffset);
546   CMICMDBASE_GETOPTION(pArgAddrExpr, String, m_constStrArgAddrExpr);
547   CMICMDBASE_GETOPTION(pArgNumBytes, Number, m_constStrArgNumBytes);
548
549   // get the --thread option value
550   MIuint64 nThreadId = UINT64_MAX;
551   if (pArgThread->GetFound() &&
552       !pArgThread->GetExpectedOption<CMICmdArgValNumber, MIuint64>(nThreadId)) {
553     SetError(CMIUtilString::Format(MIRSRC(IDS_CMD_ERR_OPTION_NOT_FOUND),
554                                    m_cmdData.strMiCmd.c_str(),
555                                    m_constStrArgThread.c_str()));
556     return MIstatus::failure;
557   }
558
559   // get the --frame option value
560   MIuint64 nFrame = UINT64_MAX;
561   if (pArgFrame->GetFound() &&
562       !pArgFrame->GetExpectedOption<CMICmdArgValNumber, MIuint64>(nFrame)) {
563     SetError(CMIUtilString::Format(MIRSRC(IDS_CMD_ERR_OPTION_NOT_FOUND),
564                                    m_cmdData.strMiCmd.c_str(),
565                                    m_constStrArgFrame.c_str()));
566     return MIstatus::failure;
567   }
568
569   // get the -o option value
570   MIuint64 nAddrOffset = 0;
571   if (pArgAddrOffset->GetFound() &&
572       !pArgAddrOffset->GetExpectedOption<CMICmdArgValNumber, MIuint64>(
573           nAddrOffset)) {
574     SetError(CMIUtilString::Format(MIRSRC(IDS_CMD_ERR_OPTION_NOT_FOUND),
575                                    m_cmdData.strMiCmd.c_str(),
576                                    m_constStrArgByteOffset.c_str()));
577     return MIstatus::failure;
578   }
579
580   CMICmnLLDBDebugSessionInfo &rSessionInfo(
581       CMICmnLLDBDebugSessionInfo::Instance());
582   lldb::SBProcess sbProcess = rSessionInfo.GetProcess();
583   if (!sbProcess.IsValid()) {
584     SetError(CMIUtilString::Format(MIRSRC(IDS_CMD_ERR_INVALID_PROCESS),
585                                    m_cmdData.strMiCmd.c_str()));
586     return MIstatus::failure;
587   }
588
589   lldb::SBThread thread = (nThreadId != UINT64_MAX)
590                               ? sbProcess.GetThreadByIndexID(nThreadId)
591                               : sbProcess.GetSelectedThread();
592   if (!thread.IsValid()) {
593     SetError(CMIUtilString::Format(MIRSRC(IDS_CMD_ERR_THREAD_INVALID),
594                                    m_cmdData.strMiCmd.c_str()));
595     return MIstatus::failure;
596   }
597
598   lldb::SBFrame frame = (nFrame != UINT64_MAX) ? thread.GetFrameAtIndex(nFrame)
599                                                : thread.GetSelectedFrame();
600   if (!frame.IsValid()) {
601     SetError(CMIUtilString::Format(MIRSRC(IDS_CMD_ERR_FRAME_INVALID),
602                                    m_cmdData.strMiCmd.c_str()));
603     return MIstatus::failure;
604   }
605
606   const CMIUtilString &rAddrExpr = pArgAddrExpr->GetValue();
607   lldb::SBValue addrExprValue = frame.EvaluateExpression(rAddrExpr.c_str());
608   lldb::SBError error = addrExprValue.GetError();
609   if (error.Fail()) {
610     SetError(error.GetCString());
611     return MIstatus::failure;
612   } else if (!addrExprValue.IsValid()) {
613     SetError(CMIUtilString::Format(MIRSRC(IDS_CMD_ERR_EXPR_INVALID),
614                                    rAddrExpr.c_str()));
615     return MIstatus::failure;
616   }
617
618   MIuint64 nAddrStart = 0;
619   if (!CMICmnLLDBProxySBValue::GetValueAsUnsigned(addrExprValue, nAddrStart)) {
620     SetError(CMIUtilString::Format(MIRSRC(IDS_CMD_ERR_EXPR_INVALID),
621                                    rAddrExpr.c_str()));
622     return MIstatus::failure;
623   }
624
625   nAddrStart += nAddrOffset;
626   const MIuint64 nAddrNumBytes = pArgNumBytes->GetValue();
627
628   m_pBufferMemory = new unsigned char[nAddrNumBytes];
629   if (m_pBufferMemory == nullptr) {
630     SetError(CMIUtilString::Format(MIRSRC(IDS_CMD_ERR_MEMORY_ALLOC_FAILURE),
631                                    m_cmdData.strMiCmd.c_str(), nAddrNumBytes));
632     return MIstatus::failure;
633   }
634
635   const MIuint64 nReadBytes =
636       sbProcess.ReadMemory(static_cast<lldb::addr_t>(nAddrStart),
637                            (void *)m_pBufferMemory, nAddrNumBytes, error);
638   if (nReadBytes != nAddrNumBytes) {
639     SetError(CMIUtilString::Format(
640         MIRSRC(IDS_CMD_ERR_LLDB_ERR_NOT_READ_WHOLE_BLK),
641         m_cmdData.strMiCmd.c_str(), nAddrNumBytes, nAddrStart));
642     return MIstatus::failure;
643   }
644   if (error.Fail()) {
645     lldb::SBStream err;
646     const bool bOk = error.GetDescription(err);
647     MIunused(bOk);
648     SetError(CMIUtilString::Format(MIRSRC(IDS_CMD_ERR_LLDB_ERR_READ_MEM_BYTES),
649                                    m_cmdData.strMiCmd.c_str(), nAddrNumBytes,
650                                    nAddrStart, err.GetData()));
651     return MIstatus::failure;
652   }
653
654   m_nAddrStart = nAddrStart;
655   m_nAddrNumBytesToRead = nAddrNumBytes;
656
657   return MIstatus::success;
658 }
659
660 //++
661 //------------------------------------------------------------------------------------
662 // Details: The invoker requires this function. The command prepares a MI Record
663 // Result
664 //          for the work carried out in the Execute().
665 // Type:    Overridden.
666 // Args:    None.
667 // Return:  MIstatus::success - Functional succeeded.
668 //          MIstatus::failure - Functional failed.
669 // Throws:  None.
670 //--
671 bool CMICmdCmdDataReadMemoryBytes::Acknowledge() {
672   // MI: memory=[{begin=\"0x%016" PRIx64 "\",offset=\"0x%016" PRIx64"
673   // \",end=\"0x%016" PRIx64 "\",contents=\" \" }]"
674   const CMICmnMIValueConst miValueConst(
675       CMIUtilString::Format("0x%016" PRIx64, m_nAddrStart));
676   const CMICmnMIValueResult miValueResult("begin", miValueConst);
677   CMICmnMIValueTuple miValueTuple(miValueResult);
678   const MIuint64 nAddrOffset = 0;
679   const CMICmnMIValueConst miValueConst2(
680       CMIUtilString::Format("0x%016" PRIx64, nAddrOffset));
681   const CMICmnMIValueResult miValueResult2("offset", miValueConst2);
682   miValueTuple.Add(miValueResult2);
683   const CMICmnMIValueConst miValueConst3(CMIUtilString::Format(
684       "0x%016" PRIx64, m_nAddrStart + m_nAddrNumBytesToRead));
685   const CMICmnMIValueResult miValueResult3("end", miValueConst3);
686   miValueTuple.Add(miValueResult3);
687
688   // MI: contents=\" \"
689   CMIUtilString strContent;
690   strContent.reserve((m_nAddrNumBytesToRead << 1) + 1);
691   for (MIuint64 i = 0; i < m_nAddrNumBytesToRead; i++) {
692     strContent += CMIUtilString::Format("%02hhx", m_pBufferMemory[i]);
693   }
694   const CMICmnMIValueConst miValueConst4(strContent);
695   const CMICmnMIValueResult miValueResult4("contents", miValueConst4);
696   miValueTuple.Add(miValueResult4);
697   const CMICmnMIValueList miValueList(miValueTuple);
698   const CMICmnMIValueResult miValueResult5("memory", miValueList);
699
700   const CMICmnMIResultRecord miRecordResult(
701       m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Done,
702       miValueResult5);
703   m_miResultRecord = miRecordResult;
704
705   return MIstatus::success;
706 }
707
708 //++
709 //------------------------------------------------------------------------------------
710 // Details: Required by the CMICmdFactory when registering *this command. The
711 // factory
712 //          calls this function to create an instance of *this command.
713 // Type:    Static method.
714 // Args:    None.
715 // Return:  CMICmdBase * - Pointer to a new command.
716 // Throws:  None.
717 //--
718 CMICmdBase *CMICmdCmdDataReadMemoryBytes::CreateSelf() {
719   return new CMICmdCmdDataReadMemoryBytes();
720 }
721
722 //---------------------------------------------------------------------------------------
723 //---------------------------------------------------------------------------------------
724 //---------------------------------------------------------------------------------------
725
726 //++
727 //------------------------------------------------------------------------------------
728 // Details: CMICmdCmdDataReadMemory constructor.
729 // Type:    Method.
730 // Args:    None.
731 // Return:  None.
732 // Throws:  None.
733 //--
734 CMICmdCmdDataReadMemory::CMICmdCmdDataReadMemory() {
735   // Command factory matches this name with that received from the stdin stream
736   m_strMiCmd = "data-read-memory";
737
738   // Required by the CMICmdFactory when registering *this command
739   m_pSelfCreatorFn = &CMICmdCmdDataReadMemory::CreateSelf;
740 }
741
742 //++
743 //------------------------------------------------------------------------------------
744 // Details: CMICmdCmdDataReadMemory destructor.
745 // Type:    Overrideable.
746 // Args:    None.
747 // Return:  None.
748 // Throws:  None.
749 //--
750 CMICmdCmdDataReadMemory::~CMICmdCmdDataReadMemory() {}
751
752 //++
753 //------------------------------------------------------------------------------------
754 // Details: The invoker requires this function. The command does work in this
755 // function.
756 //          The command is likely to communicate with the LLDB SBDebugger in
757 //          here.
758 // Type:    Overridden.
759 // Args:    None.
760 // Return:  MIstatus::success - Functional succeeded.
761 //          MIstatus::failure - Functional failed.
762 // Throws:  None.
763 //--
764 bool CMICmdCmdDataReadMemory::Execute() {
765   // Do nothing - command deprecated use "data-read-memory-bytes" command
766   return MIstatus::success;
767 }
768
769 //++
770 //------------------------------------------------------------------------------------
771 // Details: The invoker requires this function. The command prepares a MI Record
772 // Result
773 //          for the work carried out in the Execute().
774 // Type:    Overridden.
775 // Args:    None.
776 // Return:  MIstatus::success - Functional succeeded.
777 //          MIstatus::failure - Functional failed.
778 // Throws:  None.
779 //--
780 bool CMICmdCmdDataReadMemory::Acknowledge() {
781   // Command CMICmdCmdSupportListFeatures sends "data-read-memory-bytes" which
782   // causes this command not to be called
783   const CMICmnMIValueConst miValueConst(
784       MIRSRC(IDS_CMD_ERR_NOT_IMPLEMENTED_DEPRECATED));
785   const CMICmnMIValueResult miValueResult("msg", miValueConst);
786   const CMICmnMIResultRecord miRecordResult(
787       m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Error,
788       miValueResult);
789   m_miResultRecord = miRecordResult;
790
791   return MIstatus::success;
792 }
793
794 //++
795 //------------------------------------------------------------------------------------
796 // Details: Required by the CMICmdFactory when registering *this command. The
797 // factory
798 //          calls this function to create an instance of *this command.
799 // Type:    Static method.
800 // Args:    None.
801 // Return:  CMICmdBase * - Pointer to a new command.
802 // Throws:  None.
803 //--
804 CMICmdBase *CMICmdCmdDataReadMemory::CreateSelf() {
805   return new CMICmdCmdDataReadMemory();
806 }
807
808 //---------------------------------------------------------------------------------------
809 //---------------------------------------------------------------------------------------
810 //---------------------------------------------------------------------------------------
811
812 //++
813 //------------------------------------------------------------------------------------
814 // Details: CMICmdCmdDataListRegisterNames constructor.
815 // Type:    Method.
816 // Args:    None.
817 // Return:  None.
818 // Throws:  None.
819 //--
820 CMICmdCmdDataListRegisterNames::CMICmdCmdDataListRegisterNames()
821     : m_constStrArgRegNo("regno"), m_miValueList(true) {
822   // Command factory matches this name with that received from the stdin stream
823   m_strMiCmd = "data-list-register-names";
824
825   // Required by the CMICmdFactory when registering *this command
826   m_pSelfCreatorFn = &CMICmdCmdDataListRegisterNames::CreateSelf;
827 }
828
829 //++
830 //------------------------------------------------------------------------------------
831 // Details: CMICmdCmdDataReadMemoryBytes destructor.
832 // Type:    Overrideable.
833 // Args:    None.
834 // Return:  None.
835 // Throws:  None.
836 //--
837 CMICmdCmdDataListRegisterNames::~CMICmdCmdDataListRegisterNames() {}
838
839 //++
840 //------------------------------------------------------------------------------------
841 // Details: The invoker requires this function. The parses the command line
842 // options
843 //          arguments to extract values for each of those arguments.
844 // Type:    Overridden.
845 // Args:    None.
846 // Return:  MIstatus::success - Functional succeeded.
847 //          MIstatus::failure - Functional failed.
848 // Throws:  None.
849 //--
850 bool CMICmdCmdDataListRegisterNames::ParseArgs() {
851   m_setCmdArgs.Add(
852       new CMICmdArgValListOfN(m_constStrArgRegNo, false, false,
853                               CMICmdArgValListBase::eArgValType_Number));
854   return ParseValidateCmdOptions();
855 }
856
857 //++
858 //------------------------------------------------------------------------------------
859 // Details: The invoker requires this function. The command does work in this
860 // function.
861 //          The command is likely to communicate with the LLDB SBDebugger in
862 //          here.
863 // Type:    Overridden.
864 // Args:    None.
865 // Return:  MIstatus::success - Functional succeeded.
866 //          MIstatus::failure - Functional failed.
867 // Throws:  None.
868 //--
869 bool CMICmdCmdDataListRegisterNames::Execute() {
870   CMICMDBASE_GETOPTION(pArgRegNo, ListOfN, m_constStrArgRegNo);
871
872   CMICmnLLDBDebugSessionInfo &rSessionInfo(
873       CMICmnLLDBDebugSessionInfo::Instance());
874   lldb::SBProcess sbProcess = rSessionInfo.GetProcess();
875   if (!sbProcess.IsValid()) {
876     SetError(CMIUtilString::Format(MIRSRC(IDS_CMD_ERR_INVALID_PROCESS),
877                                    m_cmdData.strMiCmd.c_str()));
878     return MIstatus::failure;
879   }
880
881   const CMICmdArgValListBase::VecArgObjPtr_t &rVecRegNo(
882       pArgRegNo->GetExpectedOptions());
883   if (!rVecRegNo.empty()) {
884     // List of required registers
885     CMICmdArgValListBase::VecArgObjPtr_t::const_iterator it = rVecRegNo.begin();
886     while (it != rVecRegNo.end()) {
887       const CMICmdArgValNumber *pRegNo = static_cast<CMICmdArgValNumber *>(*it);
888       const MIuint nRegIndex = pRegNo->GetValue();
889       lldb::SBValue regValue = GetRegister(nRegIndex);
890       if (regValue.IsValid()) {
891         const CMICmnMIValueConst miValueConst(
892             CMICmnLLDBUtilSBValue(regValue).GetName());
893         m_miValueList.Add(miValueConst);
894       }
895
896       // Next
897       ++it;
898     }
899   } else {
900     // List of all registers
901     lldb::SBThread thread = sbProcess.GetSelectedThread();
902     lldb::SBFrame frame = thread.GetSelectedFrame();
903     lldb::SBValueList registers = frame.GetRegisters();
904     const MIuint nRegisters = registers.GetSize();
905     for (MIuint i = 0; i < nRegisters; i++) {
906       lldb::SBValue value = registers.GetValueAtIndex(i);
907       const MIuint nRegChildren = value.GetNumChildren();
908       for (MIuint j = 0; j < nRegChildren; j++) {
909         lldb::SBValue regValue = value.GetChildAtIndex(j);
910         if (regValue.IsValid()) {
911           const CMICmnMIValueConst miValueConst(
912               CMICmnLLDBUtilSBValue(regValue).GetName());
913           m_miValueList.Add(miValueConst);
914         }
915       }
916     }
917   }
918
919   return MIstatus::success;
920 }
921
922 //++
923 //------------------------------------------------------------------------------------
924 // Details: The invoker requires this function. The command prepares a MI Record
925 // Result
926 //          for the work carried out in the Execute().
927 // Type:    Overridden.
928 // Args:    None.
929 // Return:  MIstatus::success - Functional succeeded.
930 //          MIstatus::failure - Functional failed.
931 // Throws:  None.
932 //--
933 bool CMICmdCmdDataListRegisterNames::Acknowledge() {
934   const CMICmnMIValueResult miValueResult("register-names", m_miValueList);
935   const CMICmnMIResultRecord miRecordResult(
936       m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Done,
937       miValueResult);
938   m_miResultRecord = miRecordResult;
939
940   return MIstatus::success;
941 }
942
943 //++
944 //------------------------------------------------------------------------------------
945 // Details: Required by the CMICmdFactory when registering *this command. The
946 // factory
947 //          calls this function to create an instance of *this command.
948 // Type:    Static method.
949 // Args:    None.
950 // Return:  CMICmdBase * - Pointer to a new command.
951 // Throws:  None.
952 //--
953 CMICmdBase *CMICmdCmdDataListRegisterNames::CreateSelf() {
954   return new CMICmdCmdDataListRegisterNames();
955 }
956
957 //++
958 //------------------------------------------------------------------------------------
959 // Details: Required by the CMICmdFactory when registering *this command. The
960 // factory
961 //          calls this function to create an instance of *this command.
962 // Type:    Method.
963 // Args:    None.
964 // Return:  lldb::SBValue - LLDB SBValue object.
965 // Throws:  None.
966 //--
967 lldb::SBValue
968 CMICmdCmdDataListRegisterNames::GetRegister(const MIuint vRegisterIndex) const {
969   lldb::SBThread thread =
970       CMICmnLLDBDebugSessionInfo::Instance().GetProcess().GetSelectedThread();
971   lldb::SBFrame frame = thread.GetSelectedFrame();
972   lldb::SBValueList registers = frame.GetRegisters();
973   const MIuint nRegisters = registers.GetSize();
974   MIuint nRegisterIndex(vRegisterIndex);
975   for (MIuint i = 0; i < nRegisters; i++) {
976     lldb::SBValue value = registers.GetValueAtIndex(i);
977     const MIuint nRegChildren = value.GetNumChildren();
978     if (nRegisterIndex >= nRegChildren) {
979       nRegisterIndex -= nRegChildren;
980       continue;
981     }
982
983     lldb::SBValue value2 = value.GetChildAtIndex(nRegisterIndex);
984     if (value2.IsValid()) {
985       return value2;
986     }
987   }
988
989   return lldb::SBValue();
990 }
991
992 //---------------------------------------------------------------------------------------
993 //---------------------------------------------------------------------------------------
994 //---------------------------------------------------------------------------------------
995
996 //++
997 //------------------------------------------------------------------------------------
998 // Details: CMICmdCmdDataListRegisterValues constructor.
999 // Type:    Method.
1000 // Args:    None.
1001 // Return:  None.
1002 // Throws:  None.
1003 //--
1004 CMICmdCmdDataListRegisterValues::CMICmdCmdDataListRegisterValues()
1005     : m_constStrArgSkip("skip-unavailable"), m_constStrArgFormat("fmt"),
1006       m_constStrArgRegNo("regno"), m_miValueList(true) {
1007   // Command factory matches this name with that received from the stdin stream
1008   m_strMiCmd = "data-list-register-values";
1009
1010   // Required by the CMICmdFactory when registering *this command
1011   m_pSelfCreatorFn = &CMICmdCmdDataListRegisterValues::CreateSelf;
1012 }
1013
1014 //++
1015 //------------------------------------------------------------------------------------
1016 // Details: CMICmdCmdDataListRegisterValues destructor.
1017 // Type:    Overrideable.
1018 // Args:    None.
1019 // Return:  None.
1020 // Throws:  None.
1021 //--
1022 CMICmdCmdDataListRegisterValues::~CMICmdCmdDataListRegisterValues() {}
1023
1024 //++
1025 //------------------------------------------------------------------------------------
1026 // Details: The invoker requires this function. The parses the command line
1027 // options
1028 //          arguments to extract values for each of those arguments.
1029 // Type:    Overridden.
1030 // Args:    None.
1031 // Return:  MIstatus::success - Functional succeeded.
1032 //          MIstatus::failure - Functional failed.
1033 // Throws:  None.
1034 //--
1035 bool CMICmdCmdDataListRegisterValues::ParseArgs() {
1036   m_setCmdArgs.Add(
1037       new CMICmdArgValOptionLong(m_constStrArgThread, false, false,
1038                                  CMICmdArgValListBase::eArgValType_Number, 1));
1039   m_setCmdArgs.Add(new CMICmdArgValOptionLong(m_constStrArgSkip, false, false));
1040   m_setCmdArgs.Add(new CMICmdArgValString(m_constStrArgFormat, true, true));
1041   m_setCmdArgs.Add(
1042       new CMICmdArgValListOfN(m_constStrArgRegNo, false, true,
1043                               CMICmdArgValListBase::eArgValType_Number));
1044   return ParseValidateCmdOptions();
1045 }
1046
1047 //++
1048 //------------------------------------------------------------------------------------
1049 // Details: The invoker requires this function. The command does work in this
1050 // function.
1051 //          The command is likely to communicate with the LLDB SBDebugger in
1052 //          here.
1053 // Type:    Overridden.
1054 // Args:    None.
1055 // Return:  MIstatus::success - Functional succeeded.
1056 //          MIstatus::failure - Functional failed.
1057 // Throws:  None.
1058 //--
1059 bool CMICmdCmdDataListRegisterValues::Execute() {
1060   CMICMDBASE_GETOPTION(pArgFormat, String, m_constStrArgFormat);
1061   CMICMDBASE_GETOPTION(pArgRegNo, ListOfN, m_constStrArgRegNo);
1062
1063   const CMIUtilString &rStrFormat(pArgFormat->GetValue());
1064   if (rStrFormat.length() != 1) {
1065     SetError(CMIUtilString::Format(MIRSRC(IDS_CMD_ERR_INVALID_FORMAT_TYPE),
1066                                    m_cmdData.strMiCmd.c_str(),
1067                                    rStrFormat.c_str()));
1068     return MIstatus::failure;
1069   }
1070   const CMICmnLLDBDebugSessionInfoVarObj::varFormat_e eFormat =
1071       CMICmnLLDBDebugSessionInfoVarObj::GetVarFormatForChar(rStrFormat[0]);
1072   if (eFormat == CMICmnLLDBDebugSessionInfoVarObj::eVarFormat_Invalid) {
1073     SetError(CMIUtilString::Format(MIRSRC(IDS_CMD_ERR_INVALID_FORMAT_TYPE),
1074                                    m_cmdData.strMiCmd.c_str(),
1075                                    rStrFormat.c_str()));
1076     return MIstatus::failure;
1077   }
1078
1079   CMICmnLLDBDebugSessionInfo &rSessionInfo(
1080       CMICmnLLDBDebugSessionInfo::Instance());
1081   lldb::SBProcess sbProcess = rSessionInfo.GetProcess();
1082   if (!sbProcess.IsValid()) {
1083     SetError(CMIUtilString::Format(MIRSRC(IDS_CMD_ERR_INVALID_PROCESS),
1084                                    m_cmdData.strMiCmd.c_str()));
1085     return MIstatus::failure;
1086   }
1087
1088   const CMICmdArgValListBase::VecArgObjPtr_t &rVecRegNo(
1089       pArgRegNo->GetExpectedOptions());
1090   if (!rVecRegNo.empty()) {
1091     // List of required registers
1092     CMICmdArgValListBase::VecArgObjPtr_t::const_iterator it = rVecRegNo.begin();
1093     while (it != rVecRegNo.end()) {
1094       const CMICmdArgValNumber *pRegNo = static_cast<CMICmdArgValNumber *>(*it);
1095       const MIuint nRegIndex = pRegNo->GetValue();
1096       lldb::SBValue regValue = GetRegister(nRegIndex);
1097       if (regValue.IsValid()) {
1098         AddToOutput(nRegIndex, regValue, eFormat);
1099       }
1100
1101       // Next
1102       ++it;
1103     }
1104   } else {
1105     // No register numbers are provided. Output all registers.
1106     lldb::SBThread thread = sbProcess.GetSelectedThread();
1107     lldb::SBFrame frame = thread.GetSelectedFrame();
1108     lldb::SBValueList registers = frame.GetRegisters();
1109     const MIuint nRegisters = registers.GetSize();
1110     MIuint nRegIndex = 0;
1111     for (MIuint i = 0; i < nRegisters; i++) {
1112       lldb::SBValue value = registers.GetValueAtIndex(i);
1113       const MIuint nRegChildren = value.GetNumChildren();
1114       for (MIuint j = 0; j < nRegChildren; j++) {
1115         lldb::SBValue regValue = value.GetChildAtIndex(j);
1116         if (regValue.IsValid()) {
1117           AddToOutput(nRegIndex, regValue, eFormat);
1118         }
1119
1120         // Next
1121         ++nRegIndex;
1122       }
1123     }
1124   }
1125
1126   return MIstatus::success;
1127 }
1128
1129 //++
1130 //------------------------------------------------------------------------------------
1131 // Details: The invoker requires this function. The command prepares a MI Record
1132 // Result
1133 //          for the work carried out in the Execute().
1134 // Type:    Overridden.
1135 // Args:    None.
1136 // Return:  MIstatus::success - Functional succeeded.
1137 //          MIstatus::failure - Functional failed.
1138 // Throws:  None.
1139 //--
1140 bool CMICmdCmdDataListRegisterValues::Acknowledge() {
1141   const CMICmnMIValueResult miValueResult("register-values", m_miValueList);
1142   const CMICmnMIResultRecord miRecordResult(
1143       m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Done,
1144       miValueResult);
1145   m_miResultRecord = miRecordResult;
1146
1147   return MIstatus::success;
1148 }
1149
1150 //++
1151 //------------------------------------------------------------------------------------
1152 // Details: Required by the CMICmdFactory when registering *this command. The
1153 // factory
1154 //          calls this function to create an instance of *this command.
1155 // Type:    Static method.
1156 // Args:    None.
1157 // Return:  CMICmdBase * - Pointer to a new command.
1158 // Throws:  None.
1159 //--
1160 CMICmdBase *CMICmdCmdDataListRegisterValues::CreateSelf() {
1161   return new CMICmdCmdDataListRegisterValues();
1162 }
1163
1164 //++
1165 //------------------------------------------------------------------------------------
1166 // Details: Required by the CMICmdFactory when registering *this command. The
1167 // factory
1168 //          calls this function to create an instance of *this command.
1169 // Type:    Method.
1170 // Args:    None.
1171 // Return:  lldb::SBValue - LLDB SBValue object.
1172 // Throws:  None.
1173 //--
1174 lldb::SBValue CMICmdCmdDataListRegisterValues::GetRegister(
1175     const MIuint vRegisterIndex) const {
1176   lldb::SBThread thread =
1177       CMICmnLLDBDebugSessionInfo::Instance().GetProcess().GetSelectedThread();
1178   lldb::SBFrame frame = thread.GetSelectedFrame();
1179   lldb::SBValueList registers = frame.GetRegisters();
1180   const MIuint nRegisters = registers.GetSize();
1181   MIuint nRegisterIndex(vRegisterIndex);
1182   for (MIuint i = 0; i < nRegisters; i++) {
1183     lldb::SBValue value = registers.GetValueAtIndex(i);
1184     const MIuint nRegChildren = value.GetNumChildren();
1185     if (nRegisterIndex >= nRegChildren) {
1186       nRegisterIndex -= nRegChildren;
1187       continue;
1188     }
1189
1190     lldb::SBValue value2 = value.GetChildAtIndex(nRegisterIndex);
1191     if (value2.IsValid()) {
1192       return value2;
1193     }
1194   }
1195
1196   return lldb::SBValue();
1197 }
1198
1199 //++
1200 //------------------------------------------------------------------------------------
1201 // Details: Adds the register value to the output list.
1202 // Type:    Method.
1203 // Args:    Value of the register, its index and output format.
1204 // Return:  None
1205 // Throws:  None.
1206 //--
1207 void CMICmdCmdDataListRegisterValues::AddToOutput(
1208     const MIuint vnIndex, const lldb::SBValue &vrValue,
1209     CMICmnLLDBDebugSessionInfoVarObj::varFormat_e veVarFormat) {
1210   const CMICmnMIValueConst miValueConst(CMIUtilString::Format("%u", vnIndex));
1211   const CMICmnMIValueResult miValueResult("number", miValueConst);
1212   CMICmnMIValueTuple miValueTuple(miValueResult);
1213   const CMIUtilString strRegValue(
1214       CMICmnLLDBDebugSessionInfoVarObj::GetValueStringFormatted(vrValue,
1215                                                                 veVarFormat));
1216   const CMICmnMIValueConst miValueConst2(strRegValue);
1217   const CMICmnMIValueResult miValueResult2("value", miValueConst2);
1218   miValueTuple.Add(miValueResult2);
1219   m_miValueList.Add(miValueTuple);
1220 }
1221
1222 //---------------------------------------------------------------------------------------
1223 //---------------------------------------------------------------------------------------
1224 //---------------------------------------------------------------------------------------
1225
1226 //++
1227 //------------------------------------------------------------------------------------
1228 // Details: CMICmdCmdDataListRegisterChanged constructor.
1229 // Type:    Method.
1230 // Args:    None.
1231 // Return:  None.
1232 // Throws:  None.
1233 //--
1234 CMICmdCmdDataListRegisterChanged::CMICmdCmdDataListRegisterChanged() {
1235   // Command factory matches this name with that received from the stdin stream
1236   m_strMiCmd = "data-list-changed-registers";
1237
1238   // Required by the CMICmdFactory when registering *this command
1239   m_pSelfCreatorFn = &CMICmdCmdDataListRegisterChanged::CreateSelf;
1240 }
1241
1242 //++
1243 //------------------------------------------------------------------------------------
1244 // Details: CMICmdCmdDataListRegisterChanged destructor.
1245 // Type:    Overrideable.
1246 // Args:    None.
1247 // Return:  None.
1248 // Throws:  None.
1249 //--
1250 CMICmdCmdDataListRegisterChanged::~CMICmdCmdDataListRegisterChanged() {}
1251
1252 //++
1253 //------------------------------------------------------------------------------------
1254 // Details: The invoker requires this function. The command does work in this
1255 // function.
1256 //          The command is likely to communicate with the LLDB SBDebugger in
1257 //          here.
1258 // Type:    Overridden.
1259 // Args:    None.
1260 // Return:  MIstatus::success - Functional succeeded.
1261 //          MIstatus::failure - Functional failed.
1262 // Throws:  None.
1263 //--
1264 bool CMICmdCmdDataListRegisterChanged::Execute() {
1265   // Do nothing
1266
1267   return MIstatus::success;
1268 }
1269
1270 //++
1271 //------------------------------------------------------------------------------------
1272 // Details: The invoker requires this function. The command prepares a MI Record
1273 // Result
1274 //          for the work carried out in the Execute().
1275 // Type:    Overridden.
1276 // Args:    None.
1277 // Return:  MIstatus::success - Functional succeeded.
1278 //          MIstatus::failure - Functional failed.
1279 // Throws:  None.
1280 //--
1281 bool CMICmdCmdDataListRegisterChanged::Acknowledge() {
1282   const CMICmnMIValueConst miValueConst(MIRSRC(IDS_WORD_NOT_IMPLEMENTED));
1283   const CMICmnMIValueResult miValueResult("msg", miValueConst);
1284   const CMICmnMIResultRecord miRecordResult(
1285       m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Error,
1286       miValueResult);
1287   m_miResultRecord = miRecordResult;
1288
1289   return MIstatus::success;
1290 }
1291
1292 //++
1293 //------------------------------------------------------------------------------------
1294 // Details: Required by the CMICmdFactory when registering *this command. The
1295 // factory
1296 //          calls this function to create an instance of *this command.
1297 // Type:    Static method.
1298 // Args:    None.
1299 // Return:  CMICmdBase * - Pointer to a new command.
1300 // Throws:  None.
1301 //--
1302 CMICmdBase *CMICmdCmdDataListRegisterChanged::CreateSelf() {
1303   return new CMICmdCmdDataListRegisterChanged();
1304 }
1305
1306 //---------------------------------------------------------------------------------------
1307 //---------------------------------------------------------------------------------------
1308 //---------------------------------------------------------------------------------------
1309
1310 //++
1311 //------------------------------------------------------------------------------------
1312 // Details: CMICmdCmdDataWriteMemoryBytes constructor.
1313 // Type:    Method.
1314 // Args:    None.
1315 // Return:  None.
1316 // Throws:  None.
1317 //--
1318 CMICmdCmdDataWriteMemoryBytes::CMICmdCmdDataWriteMemoryBytes()
1319     : m_constStrArgAddr("address"), m_constStrArgContents("contents"),
1320       m_constStrArgCount("count") {
1321   // Command factory matches this name with that received from the stdin stream
1322   m_strMiCmd = "data-write-memory-bytes";
1323
1324   // Required by the CMICmdFactory when registering *this command
1325   m_pSelfCreatorFn = &CMICmdCmdDataWriteMemoryBytes::CreateSelf;
1326 }
1327
1328 //++
1329 //------------------------------------------------------------------------------------
1330 // Details: CMICmdCmdDataWriteMemoryBytes destructor.
1331 // Type:    Overrideable.
1332 // Args:    None.
1333 // Return:  None.
1334 // Throws:  None.
1335 //--
1336 CMICmdCmdDataWriteMemoryBytes::~CMICmdCmdDataWriteMemoryBytes() {}
1337
1338 //++
1339 //------------------------------------------------------------------------------------
1340 // Details: The invoker requires this function. The parses the command line
1341 // options
1342 //          arguments to extract values for each of those arguments.
1343 // Type:    Overridden.
1344 // Args:    None.
1345 // Return:  MIstatus::success - Functional succeeded.
1346 //          MIstatus::failure - Functional failed.
1347 // Throws:  None.
1348 //--
1349 bool CMICmdCmdDataWriteMemoryBytes::ParseArgs() {
1350   m_setCmdArgs.Add(
1351       new CMICmdArgValString(m_constStrArgAddr, true, true, false, true));
1352   m_setCmdArgs.Add(
1353       new CMICmdArgValString(m_constStrArgContents, true, true, true, true));
1354   m_setCmdArgs.Add(
1355       new CMICmdArgValString(m_constStrArgCount, false, true, false, true));
1356   return ParseValidateCmdOptions();
1357 }
1358
1359 //++
1360 //------------------------------------------------------------------------------------
1361 // Details: The invoker requires this function. The command does work in this
1362 // function.
1363 //          The command is likely to communicate with the LLDB SBDebugger in
1364 //          here.
1365 // Type:    Overridden.
1366 // Args:    None.
1367 // Return:  MIstatus::success - Functional succeeded.
1368 //          MIstatus::failure - Functional failed.
1369 // Throws:  None.
1370 //--
1371 bool CMICmdCmdDataWriteMemoryBytes::Execute() {
1372   // Do nothing - not reproduceable (yet) in Eclipse
1373   // CMICMDBASE_GETOPTION( pArgOffset, OptionShort, m_constStrArgOffset );
1374   // CMICMDBASE_GETOPTION( pArgAddr, String, m_constStrArgAddr );
1375   // CMICMDBASE_GETOPTION( pArgNumber, String, m_constStrArgNumber );
1376   // CMICMDBASE_GETOPTION( pArgContents, String, m_constStrArgContents );
1377   //
1378   // Numbers extracts as string types as they could be hex numbers
1379   // '&' is not recognised and so has to be removed
1380
1381   return MIstatus::success;
1382 }
1383
1384 //++
1385 //------------------------------------------------------------------------------------
1386 // Details: The invoker requires this function. The command prepares a MI Record
1387 // Result
1388 //          for the work carried out in the Execute().
1389 // Type:    Overridden.
1390 // Args:    None.
1391 // Return:  MIstatus::success - Functional succeeded.
1392 //          MIstatus::failure - Functional failed.
1393 // Throws:  None.
1394 //--
1395 bool CMICmdCmdDataWriteMemoryBytes::Acknowledge() {
1396   const CMICmnMIValueConst miValueConst(MIRSRC(IDS_WORD_NOT_IMPLEMENTED));
1397   const CMICmnMIValueResult miValueResult("msg", miValueConst);
1398   const CMICmnMIResultRecord miRecordResult(
1399       m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Error,
1400       miValueResult);
1401   m_miResultRecord = miRecordResult;
1402
1403   return MIstatus::success;
1404 }
1405
1406 //++
1407 //------------------------------------------------------------------------------------
1408 // Details: Required by the CMICmdFactory when registering *this command. The
1409 // factory
1410 //          calls this function to create an instance of *this command.
1411 // Type:    Static method.
1412 // Args:    None.
1413 // Return:  CMICmdBase * - Pointer to a new command.
1414 // Throws:  None.
1415 //--
1416 CMICmdBase *CMICmdCmdDataWriteMemoryBytes::CreateSelf() {
1417   return new CMICmdCmdDataWriteMemoryBytes();
1418 }
1419
1420 //---------------------------------------------------------------------------------------
1421 //---------------------------------------------------------------------------------------
1422 //---------------------------------------------------------------------------------------
1423
1424 //++
1425 //------------------------------------------------------------------------------------
1426 // Details: CMICmdCmdDataWriteMemory constructor.
1427 // Type:    Method.
1428 // Args:    None.
1429 // Return:  None.
1430 // Throws:  None.
1431 //--
1432 CMICmdCmdDataWriteMemory::CMICmdCmdDataWriteMemory()
1433     : m_constStrArgOffset("o"), m_constStrArgAddr("address"),
1434       m_constStrArgD("d"), m_constStrArgNumber("a number"),
1435       m_constStrArgContents("contents"), m_nAddr(0), m_nCount(0),
1436       m_pBufferMemory(nullptr) {
1437   // Command factory matches this name with that received from the stdin stream
1438   m_strMiCmd = "data-write-memory";
1439
1440   // Required by the CMICmdFactory when registering *this command
1441   m_pSelfCreatorFn = &CMICmdCmdDataWriteMemory::CreateSelf;
1442 }
1443
1444 //++
1445 //------------------------------------------------------------------------------------
1446 // Details: CMICmdCmdDataWriteMemory destructor.
1447 // Type:    Overrideable.
1448 // Args:    None.
1449 // Return:  None.
1450 // Throws:  None.
1451 //--
1452 CMICmdCmdDataWriteMemory::~CMICmdCmdDataWriteMemory() {
1453   if (m_pBufferMemory != nullptr) {
1454     delete[] m_pBufferMemory;
1455     m_pBufferMemory = nullptr;
1456   }
1457 }
1458
1459 //++
1460 //------------------------------------------------------------------------------------
1461 // Details: The invoker requires this function. The parses the command line
1462 // options
1463 //          arguments to extract values for each of those arguments.
1464 // Type:    Overridden.
1465 // Args:    None.
1466 // Return:  MIstatus::success - Functional succeeded.
1467 //          MIstatus::failure - Functional failed.
1468 // Throws:  None.
1469 //--
1470 bool CMICmdCmdDataWriteMemory::ParseArgs() {
1471   m_setCmdArgs.Add(
1472       new CMICmdArgValOptionShort(m_constStrArgOffset, false, true,
1473                                   CMICmdArgValListBase::eArgValType_Number, 1));
1474   m_setCmdArgs.Add(new CMICmdArgValNumber(m_constStrArgAddr, true, true));
1475   m_setCmdArgs.Add(new CMICmdArgValString(m_constStrArgD, true, true));
1476   m_setCmdArgs.Add(new CMICmdArgValNumber(m_constStrArgNumber, true, true));
1477   m_setCmdArgs.Add(new CMICmdArgValNumber(m_constStrArgContents, true, true));
1478   return ParseValidateCmdOptions();
1479 }
1480
1481 //++
1482 //------------------------------------------------------------------------------------
1483 // Details: The invoker requires this function. The command does work in this
1484 // function.
1485 //          The command is likely to communicate with the LLDB SBDebugger in
1486 //          here.
1487 // Type:    Overridden.
1488 // Args:    None.
1489 // Return:  MIstatus::success - Functional succeeded.
1490 //          MIstatus::failure - Functional failed.
1491 // Throws:  None.
1492 //--
1493 bool CMICmdCmdDataWriteMemory::Execute() {
1494   CMICMDBASE_GETOPTION(pArgOffset, OptionShort, m_constStrArgOffset);
1495   CMICMDBASE_GETOPTION(pArgAddr, Number, m_constStrArgAddr);
1496   CMICMDBASE_GETOPTION(pArgNumber, Number, m_constStrArgNumber);
1497   CMICMDBASE_GETOPTION(pArgContents, Number, m_constStrArgContents);
1498
1499   MIuint nAddrOffset = 0;
1500   if (pArgOffset->GetFound() &&
1501       !pArgOffset->GetExpectedOption<CMICmdArgValNumber, MIuint>(nAddrOffset)) {
1502     SetError(CMIUtilString::Format(MIRSRC(IDS_CMD_ARGS_ERR_VALIDATION_INVALID),
1503                                    m_cmdData.strMiCmd.c_str(),
1504                                    m_constStrArgAddr.c_str()));
1505     return MIstatus::failure;
1506   }
1507   m_nAddr = pArgAddr->GetValue();
1508   m_nCount = pArgNumber->GetValue();
1509   const MIuint64 nValue = pArgContents->GetValue();
1510
1511   m_pBufferMemory = new unsigned char[m_nCount];
1512   if (m_pBufferMemory == nullptr) {
1513     SetError(CMIUtilString::Format(MIRSRC(IDS_CMD_ERR_MEMORY_ALLOC_FAILURE),
1514                                    m_cmdData.strMiCmd.c_str(), m_nCount));
1515     return MIstatus::failure;
1516   }
1517   *m_pBufferMemory = static_cast<char>(nValue);
1518
1519   CMICmnLLDBDebugSessionInfo &rSessionInfo(
1520       CMICmnLLDBDebugSessionInfo::Instance());
1521   lldb::SBProcess sbProcess = rSessionInfo.GetProcess();
1522   lldb::SBError error;
1523   lldb::addr_t addr = static_cast<lldb::addr_t>(m_nAddr + nAddrOffset);
1524   const size_t nBytesWritten = sbProcess.WriteMemory(
1525       addr, (const void *)m_pBufferMemory, (size_t)m_nCount, error);
1526   if (nBytesWritten != static_cast<size_t>(m_nCount)) {
1527     SetError(
1528         CMIUtilString::Format(MIRSRC(IDS_CMD_ERR_LLDB_ERR_NOT_WRITE_WHOLEBLK),
1529                               m_cmdData.strMiCmd.c_str(), m_nCount, addr));
1530     return MIstatus::failure;
1531   }
1532   if (error.Fail()) {
1533     lldb::SBStream err;
1534     const bool bOk = error.GetDescription(err);
1535     MIunused(bOk);
1536     SetError(CMIUtilString::Format(MIRSRC(IDS_CMD_ERR_LLDB_ERR_WRITE_MEM_BYTES),
1537                                    m_cmdData.strMiCmd.c_str(), m_nCount, addr,
1538                                    err.GetData()));
1539     return MIstatus::failure;
1540   }
1541
1542   return MIstatus::success;
1543 }
1544
1545 //++
1546 //------------------------------------------------------------------------------------
1547 // Details: The invoker requires this function. The command prepares a MI Record
1548 // Result
1549 //          for the work carried out in the Execute().
1550 // Type:    Overridden.
1551 // Args:    None.
1552 // Return:  MIstatus::success - Functional succeeded.
1553 //          MIstatus::failure - Functional failed.
1554 // Throws:  None.
1555 //--
1556 bool CMICmdCmdDataWriteMemory::Acknowledge() {
1557   const CMICmnMIResultRecord miRecordResult(
1558       m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Done);
1559   m_miResultRecord = miRecordResult;
1560
1561   return MIstatus::success;
1562 }
1563
1564 //++
1565 //------------------------------------------------------------------------------------
1566 // Details: Required by the CMICmdFactory when registering *this command. The
1567 // factory
1568 //          calls this function to create an instance of *this command.
1569 // Type:    Static method.
1570 // Args:    None.
1571 // Return:  CMICmdBase * - Pointer to a new command.
1572 // Throws:  None.
1573 //--
1574 CMICmdBase *CMICmdCmdDataWriteMemory::CreateSelf() {
1575   return new CMICmdCmdDataWriteMemory();
1576 }
1577
1578 //---------------------------------------------------------------------------------------
1579 //---------------------------------------------------------------------------------------
1580 //---------------------------------------------------------------------------------------
1581
1582 //++
1583 //------------------------------------------------------------------------------------
1584 // Details: CMICmdCmdDataInfoLine constructor.
1585 // Type:    Method.
1586 // Args:    None.
1587 // Return:  None.
1588 // Throws:  None.
1589 //--
1590 CMICmdCmdDataInfoLine::CMICmdCmdDataInfoLine()
1591     : m_constStrArgLocation("location") {
1592   // Command factory matches this name with that received from the stdin stream
1593   m_strMiCmd = "data-info-line";
1594
1595   // Required by the CMICmdFactory when registering *this command
1596   m_pSelfCreatorFn = &CMICmdCmdDataInfoLine::CreateSelf;
1597 }
1598
1599 //++
1600 //------------------------------------------------------------------------------------
1601 // Details: CMICmdCmdDataInfoLine destructor.
1602 // Type:    Overrideable.
1603 // Args:    None.
1604 // Return:  None.
1605 // Throws:  None.
1606 //--
1607 CMICmdCmdDataInfoLine::~CMICmdCmdDataInfoLine() {}
1608
1609 //++
1610 //------------------------------------------------------------------------------------
1611 // Details: The invoker requires this function. The parses the command line
1612 // options
1613 //          arguments to extract values for each of those arguments.
1614 // Type:    Overridden.
1615 // Args:    None.
1616 // Return:  MIstatus::success - Functional succeeded.
1617 //          MIstatus::failure - Functional failed.
1618 // Throws:  None.
1619 //--
1620 bool CMICmdCmdDataInfoLine::ParseArgs() {
1621   m_setCmdArgs.Add(new CMICmdArgValString(m_constStrArgLocation, true, true));
1622   return ParseValidateCmdOptions();
1623 }
1624
1625 //++
1626 //------------------------------------------------------------------------------------
1627 // Details: The invoker requires this function. The command does work in this
1628 // function.
1629 //          The command is likely to communicate with the LLDB SBDebugger in
1630 //          here.
1631 // Type:    Overridden.
1632 // Args:    None.
1633 // Return:  MIstatus::success - Functional succeeded.
1634 //          MIstatus::failure - Functional failed.
1635 // Throws:  None.
1636 //--
1637 bool CMICmdCmdDataInfoLine::Execute() {
1638   CMICMDBASE_GETOPTION(pArgLocation, String, m_constStrArgLocation);
1639
1640   const CMIUtilString &strLocation(pArgLocation->GetValue());
1641   CMIUtilString strCmdOptionsLocation;
1642   if (strLocation.at(0) == '*') {
1643     // Parse argument:
1644     // *0x12345
1645     //  ^^^^^^^ -- address
1646     const CMIUtilString strAddress(strLocation.substr(1));
1647     strCmdOptionsLocation =
1648         CMIUtilString::Format("--address %s", strAddress.c_str());
1649   } else {
1650     const size_t nLineStartPos = strLocation.rfind(':');
1651     if ((nLineStartPos == std::string::npos) || (nLineStartPos == 0) ||
1652         (nLineStartPos == strLocation.length() - 1)) {
1653       SetError(
1654           CMIUtilString::Format(MIRSRC(IDS_CMD_ERR_INVALID_LOCATION_FORMAT),
1655                                 m_cmdData.strMiCmd.c_str(), strLocation.c_str())
1656               .c_str());
1657       return MIstatus::failure;
1658     }
1659     // Parse argument:
1660     // hello.cpp:5
1661     // ^^^^^^^^^ -- file
1662     //           ^ -- line
1663     const CMIUtilString strFile(strLocation.substr(0, nLineStartPos));
1664     const CMIUtilString strLine(strLocation.substr(nLineStartPos + 1));
1665     strCmdOptionsLocation =
1666         CMIUtilString::Format("--file \"%s\" --line %s",
1667                               strFile.AddSlashes().c_str(), strLine.c_str());
1668   }
1669   const CMIUtilString strCmd(CMIUtilString::Format(
1670       "target modules lookup -v %s", strCmdOptionsLocation.c_str()));
1671
1672   CMICmnLLDBDebugSessionInfo &rSessionInfo(
1673       CMICmnLLDBDebugSessionInfo::Instance());
1674   const lldb::ReturnStatus rtn =
1675       rSessionInfo.GetDebugger().GetCommandInterpreter().HandleCommand(
1676           strCmd.c_str(), m_lldbResult);
1677   MIunused(rtn);
1678
1679   return MIstatus::success;
1680 }
1681
1682 //++
1683 //------------------------------------------------------------------------------------
1684 // Details: Helper function for parsing a line entry returned from lldb for the
1685 // command:
1686 //              target modules lookup -v <location>
1687 //          where the line entry is of the format:
1688 //              LineEntry: \[0x0000000100000f37-0x0000000100000f45\):
1689 //              /path/file:3[:1]
1690 //                           start              end                   file
1691 //                           line column(opt)
1692 // Args:    input - (R) Input string to parse.
1693 //          start - (W) String representing the start address.
1694 //          end   - (W) String representing the end address.
1695 //          file  - (W) String representing the file.
1696 //          line  - (W) String representing the line.
1697 // Return:  bool - True = input was parsed successfully, false = input could not
1698 // be parsed.
1699 // Throws:  None.
1700 //--
1701 static bool ParseLLDBLineEntry(const char *input, CMIUtilString &start,
1702                                CMIUtilString &end, CMIUtilString &file,
1703                                CMIUtilString &line) {
1704   // Note: Ambiguities arise because the column is optional, and
1705   // because : can appear in filenames or as a byte in a multibyte
1706   // UTF8 character.  We keep those cases to a minimum by using regex
1707   // to work on the string from both the left and right, so that what
1708   // is remains is assumed to be the filename.
1709
1710   // Match LineEntry using regex.
1711   static llvm::Regex g_lineentry_nocol_regex(llvm::StringRef(
1712       "^ *LineEntry: \\[(0x[0-9a-fA-F]+)-(0x[0-9a-fA-F]+)\\): (.+):([0-9]+)$"));
1713   static llvm::Regex g_lineentry_col_regex(
1714       llvm::StringRef("^ *LineEntry: \\[(0x[0-9a-fA-F]+)-(0x[0-9a-fA-F]+)\\): "
1715                       "(.+):([0-9]+):[0-9]+$"));
1716   //                                ^1=start         ^2=end               ^3=f
1717   //                                ^4=line ^5=:col(opt)
1718
1719   llvm::SmallVector<llvm::StringRef, 6> match;
1720
1721   // First try matching the LineEntry with the column,
1722   // then try without the column.
1723   const bool ok = g_lineentry_col_regex.match(input, &match) ||
1724                   g_lineentry_nocol_regex.match(input, &match);
1725   if (ok) {
1726     start = match[1];
1727     end = match[2];
1728     file = match[3];
1729     line = match[4];
1730   }
1731   return ok;
1732 }
1733
1734 //++
1735 //------------------------------------------------------------------------------------
1736 // Details: The invoker requires this function. The command prepares a MI Record
1737 // Result
1738 //          for the work carried out in the Execute().
1739 // Type:    Overridden.
1740 // Args:    None.
1741 // Return:  MIstatus::success - Functional succeeded.
1742 //          MIstatus::failure - Functional failed.
1743 // Throws:  None.
1744 //--
1745 bool CMICmdCmdDataInfoLine::Acknowledge() {
1746   if (m_lldbResult.GetErrorSize() > 0) {
1747     const CMICmnMIValueConst miValueConst(m_lldbResult.GetError());
1748     const CMICmnMIValueResult miValueResult("msg", miValueConst);
1749     const CMICmnMIResultRecord miRecordResult(
1750         m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Error,
1751         miValueResult);
1752     m_miResultRecord = miRecordResult;
1753     return MIstatus::success;
1754   } else if (m_lldbResult.GetOutputSize() > 0) {
1755     CMIUtilString::VecString_t vecLines;
1756     const CMIUtilString strLldbMsg(m_lldbResult.GetOutput());
1757     const MIuint nLines(strLldbMsg.SplitLines(vecLines));
1758
1759     for (MIuint i = 0; i < nLines; ++i) {
1760       // String looks like:
1761       // LineEntry: \[0x0000000100000f37-0x0000000100000f45\):
1762       // /path/to/file:3[:1]
1763       const CMIUtilString &rLine(vecLines[i]);
1764       CMIUtilString strStart;
1765       CMIUtilString strEnd;
1766       CMIUtilString strFile;
1767       CMIUtilString strLine;
1768
1769       if (!ParseLLDBLineEntry(rLine.c_str(), strStart, strEnd, strFile,
1770                               strLine))
1771         continue;
1772
1773       const CMICmnMIValueConst miValueConst(strStart);
1774       const CMICmnMIValueResult miValueResult("start", miValueConst);
1775       CMICmnMIResultRecord miRecordResult(
1776           m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Done,
1777           miValueResult);
1778       const CMICmnMIValueConst miValueConst2(strEnd);
1779       const CMICmnMIValueResult miValueResult2("end", miValueConst2);
1780       miRecordResult.Add(miValueResult2);
1781       const CMICmnMIValueConst miValueConst3(strFile);
1782       const CMICmnMIValueResult miValueResult3("file", miValueConst3);
1783       miRecordResult.Add(miValueResult3);
1784       const CMICmnMIValueConst miValueConst4(strLine);
1785       const CMICmnMIValueResult miValueResult4("line", miValueConst4);
1786       miRecordResult.Add(miValueResult4);
1787
1788       // MI print "%s^done,start=\"%d\",end=\"%d\"",file=\"%s\",line=\"%d\"
1789       m_miResultRecord = miRecordResult;
1790
1791       return MIstatus::success;
1792     }
1793   }
1794
1795   // MI print "%s^error,msg=\"Command '-data-info-line'. Error: The LineEntry is
1796   // absent or has an unknown format.\""
1797   const CMICmnMIValueConst miValueConst(CMIUtilString::Format(
1798       MIRSRC(IDS_CMD_ERR_SOME_ERROR), m_cmdData.strMiCmd.c_str(),
1799       "The LineEntry is absent or has an unknown format."));
1800   const CMICmnMIValueResult miValueResult("msg", miValueConst);
1801   const CMICmnMIResultRecord miRecordResult(
1802       m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Error,
1803       miValueResult);
1804   m_miResultRecord = miRecordResult;
1805
1806   return MIstatus::success;
1807 }
1808
1809 //++
1810 //------------------------------------------------------------------------------------
1811 // Details: Required by the CMICmdFactory when registering *this command. The
1812 // factory
1813 //          calls this function to create an instance of *this command.
1814 // Type:    Static method.
1815 // Args:    None.
1816 // Return:  CMICmdBase * - Pointer to a new command.
1817 // Throws:  None.
1818 //--
1819 CMICmdBase *CMICmdCmdDataInfoLine::CreateSelf() {
1820   return new CMICmdCmdDataInfoLine();
1821 }