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