blob: b7688d7b03cebbd4de67a1170672df8ed8109b39 [file] [log] [blame]
Deepak Panickal6f9c4682014-05-16 10:51:01 +00001//===-- 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//++
Zachary Turner1d6af022014-11-17 18:06:21 +000011// File: MICmdCmdData.cpp
Deepak Panickal6f9c4682014-05-16 10:51:01 +000012//
Zachary Turner1d6af022014-11-17 18:06:21 +000013// Overview: CMICmdCmdDataEvaluateExpression implementation.
14// CMICmdCmdDataDisassemble implementation.
15// CMICmdCmdDataReadMemoryBytes implementation.
16// CMICmdCmdDataReadMemory implementation.
17// CMICmdCmdDataListRegisterNames implementation.
18// CMICmdCmdDataListRegisterValues implementation.
19// CMICmdCmdDataListRegisterChanged implementation.
20// CMICmdCmdDataWriteMemoryBytes implementation.
21// CMICmdCmdDataWriteMemory implementation.
Deepak Panickal6f9c4682014-05-16 10:51:01 +000022//
Zachary Turner1d6af022014-11-17 18:06:21 +000023// Environment: Compilers: Visual C++ 12.
24// gcc (Ubuntu/Linaro 4.8.1-10ubuntu9) 4.8.1
25// Libraries: See MIReadmetxt.
Deepak Panickal6f9c4682014-05-16 10:51:01 +000026//
Zachary Turner1d6af022014-11-17 18:06:21 +000027// Copyright: None.
Deepak Panickal6f9c4682014-05-16 10:51:01 +000028//--
29
30// Third Party Headers:
Greg Claytonee3626e2015-01-20 00:04:26 +000031#include "lldb/API/SBThread.h"
32#include "lldb/API/SBInstruction.h"
33#include "lldb/API/SBInstructionList.h"
34#include "lldb/API/SBStream.h"
Deepak Panickal6f9c4682014-05-16 10:51:01 +000035
36// In-house headers:
Deepak Panickal6f9c4682014-05-16 10:51:01 +000037#include "MICmdCmdData.h"
38#include "MICmnMIResultRecord.h"
39#include "MICmnMIValueConst.h"
Deepak Panickal6f9c4682014-05-16 10:51:01 +000040#include "MICmnLLDBDebugger.h"
41#include "MICmnLLDBDebugSessionInfo.h"
42#include "MICmnLLDBProxySBValue.h"
Deepak Panickal6f9c4682014-05-16 10:51:01 +000043#include "MICmdArgValNumber.h"
44#include "MICmdArgValString.h"
45#include "MICmdArgValThreadGrp.h"
46#include "MICmdArgValOptionLong.h"
47#include "MICmdArgValOptionShort.h"
48#include "MICmdArgValListOfN.h"
Deepak Panickal877569c2014-06-24 16:35:50 +000049#include "MICmdArgValConsume.h"
50#include "MICmnLLDBDebugSessionInfoVarObj.h"
Deepak Panickald2499282014-08-08 16:47:42 +000051#include "MICmnLLDBUtilSBValue.h"
Deepak Panickal6f9c4682014-05-16 10:51:01 +000052
53//++ ------------------------------------------------------------------------------------
Zachary Turner1d6af022014-11-17 18:06:21 +000054// Details: CMICmdCmdDataEvaluateExpression constructor.
55// Type: Method.
56// Args: None.
57// Return: None.
58// Throws: None.
Deepak Panickal6f9c4682014-05-16 10:51:01 +000059//--
Zachary Turner1d6af022014-11-17 18:06:21 +000060CMICmdCmdDataEvaluateExpression::CMICmdCmdDataEvaluateExpression(void)
61 : m_bExpressionValid(true)
62 , m_bEvaluatedExpression(true)
63 , m_strValue("??")
64 , m_bCompositeVarType(false)
65 , m_bFoundInvalidChar(false)
66 , m_cExpressionInvalidChar(0x00)
67 , m_constStrArgThread("thread")
68 , m_constStrArgFrame("frame")
69 , m_constStrArgExpr("expr")
Deepak Panickal6f9c4682014-05-16 10:51:01 +000070{
Zachary Turner1d6af022014-11-17 18:06:21 +000071 // Command factory matches this name with that received from the stdin stream
72 m_strMiCmd = "data-evaluate-expression";
73
74 // Required by the CMICmdFactory when registering *this command
75 m_pSelfCreatorFn = &CMICmdCmdDataEvaluateExpression::CreateSelf;
Deepak Panickal6f9c4682014-05-16 10:51:01 +000076}
77
78//++ ------------------------------------------------------------------------------------
Zachary Turner1d6af022014-11-17 18:06:21 +000079// Details: CMICmdCmdDataEvaluateExpression destructor.
80// Type: Overrideable.
81// Args: None.
82// Return: None.
83// Throws: None.
Deepak Panickal6f9c4682014-05-16 10:51:01 +000084//--
Zachary Turner1d6af022014-11-17 18:06:21 +000085CMICmdCmdDataEvaluateExpression::~CMICmdCmdDataEvaluateExpression(void)
Deepak Panickal6f9c4682014-05-16 10:51:01 +000086{
87}
88
89//++ ------------------------------------------------------------------------------------
Zachary Turner1d6af022014-11-17 18:06:21 +000090// Details: The invoker requires this function. The parses the command line options
91// arguments to extract values for each of those arguments.
92// Type: Overridden.
93// Args: None.
94// Return: MIstatus::success - Functional succeeded.
95// MIstatus::failure - Functional failed.
96// Throws: None.
Deepak Panickal6f9c4682014-05-16 10:51:01 +000097//--
Zachary Turner1d6af022014-11-17 18:06:21 +000098bool
99CMICmdCmdDataEvaluateExpression::ParseArgs(void)
Deepak Panickal6f9c4682014-05-16 10:51:01 +0000100{
Zachary Turner1d6af022014-11-17 18:06:21 +0000101 bool bOk =
102 m_setCmdArgs.Add(*(new CMICmdArgValOptionLong(m_constStrArgThread, false, false, CMICmdArgValListBase::eArgValType_Number, 1)));
103 bOk = bOk &&
104 m_setCmdArgs.Add(*(new CMICmdArgValOptionLong(m_constStrArgFrame, false, false, CMICmdArgValListBase::eArgValType_Number, 1)));
105 bOk = bOk && m_setCmdArgs.Add(*(new CMICmdArgValString(m_constStrArgExpr, true, true, true, true)));
106 return (bOk && ParseValidateCmdOptions());
Deepak Panickal6f9c4682014-05-16 10:51:01 +0000107}
108
109//++ ------------------------------------------------------------------------------------
Zachary Turner1d6af022014-11-17 18:06:21 +0000110// Details: The invoker requires this function. The command does work in this function.
111// The command is likely to communicate with the LLDB SBDebugger in here.
112// Type: Overridden.
113// Args: None.
114// Return: MIstatus::success - Functional succeeded.
115// MIstatus::failure - Functional failed.
116// Throws: None.
Deepak Panickal6f9c4682014-05-16 10:51:01 +0000117//--
Zachary Turner1d6af022014-11-17 18:06:21 +0000118bool
119CMICmdCmdDataEvaluateExpression::Execute(void)
Deepak Panickal6f9c4682014-05-16 10:51:01 +0000120{
Zachary Turner1d6af022014-11-17 18:06:21 +0000121 CMICMDBASE_GETOPTION(pArgExpr, String, m_constStrArgExpr);
Deepak Panickal6f9c4682014-05-16 10:51:01 +0000122
Zachary Turner1d6af022014-11-17 18:06:21 +0000123 const CMIUtilString &rExpression(pArgExpr->GetValue());
124 CMICmnLLDBDebugSessionInfo &rSessionInfo(CMICmnLLDBDebugSessionInfo::Instance());
Hafiz Abid Qadeer0d51c152015-02-03 10:05:54 +0000125 lldb::SBProcess sbProcess = rSessionInfo.GetProcess();
126 lldb::SBThread thread = sbProcess.GetSelectedThread();
Zachary Turner1d6af022014-11-17 18:06:21 +0000127 m_bExpressionValid = (thread.GetNumFrames() > 0);
128 if (!m_bExpressionValid)
129 return MIstatus::success;
Deepak Panickald2499282014-08-08 16:47:42 +0000130
Zachary Turner1d6af022014-11-17 18:06:21 +0000131 lldb::SBFrame frame = thread.GetSelectedFrame();
132 lldb::SBValue value = frame.EvaluateExpression(rExpression.c_str());
133 if (!value.IsValid())
134 value = frame.FindVariable(rExpression.c_str());
135 if (!value.IsValid())
136 {
137 m_bEvaluatedExpression = false;
138 return MIstatus::success;
139 }
140 const CMICmnLLDBUtilSBValue utilValue(value);
141 if (!utilValue.HasName())
142 {
143 if (HaveInvalidCharacterInExpression(rExpression, m_cExpressionInvalidChar))
144 {
145 m_bFoundInvalidChar = true;
146 return MIstatus::success;
147 }
Deepak Panickal6f9c4682014-05-16 10:51:01 +0000148
Zachary Turner1d6af022014-11-17 18:06:21 +0000149 m_strValue = rExpression;
150 return MIstatus::success;
151 }
152 if (rExpression.IsQuoted())
153 {
154 m_strValue = rExpression.Trim('\"');
155 return MIstatus::success;
156 }
Deepak Panickal6f9c4682014-05-16 10:51:01 +0000157
Zachary Turner1d6af022014-11-17 18:06:21 +0000158 MIuint64 nNumber = 0;
159 if (CMICmnLLDBProxySBValue::GetValueAsUnsigned(value, nNumber) == MIstatus::success)
160 {
161 const lldb::ValueType eValueType = value.GetValueType();
162 MIunused(eValueType);
163 m_strValue = utilValue.GetValue();
164 CMIUtilString strCString;
165 if (CMICmnLLDBProxySBValue::GetCString(value, strCString))
166 {
167 m_strValue += CMIUtilString::Format(" '%s'", strCString.c_str());
168 }
169 return MIstatus::success;
170 }
Deepak Panickal6f9c4682014-05-16 10:51:01 +0000171
Zachary Turner1d6af022014-11-17 18:06:21 +0000172 // Composite type i.e. struct
173 m_bCompositeVarType = true;
174 const MIuint nChild = value.GetNumChildren();
175 for (MIuint i = 0; i < nChild; i++)
176 {
177 lldb::SBValue member = value.GetChildAtIndex(i);
178 const bool bValid = member.IsValid();
179 CMIUtilString strType(MIRSRC(IDS_WORD_UNKNOWNTYPE_BRKTS));
180 if (bValid)
181 {
182 const CMIUtilString strValue(
183 CMICmnLLDBDebugSessionInfoVarObj::GetValueStringFormatted(member, CMICmnLLDBDebugSessionInfoVarObj::eVarFormat_Natural));
184 const char *pTypeName = member.GetName();
185 if (pTypeName != nullptr)
186 strType = pTypeName;
187
188 // MI print "{variable = 1, variable2 = 3, variable3 = 5}"
189 const bool bNoQuotes = true;
190 const CMICmnMIValueConst miValueConst(strValue, bNoQuotes);
191 const bool bUseSpaces = true;
192 const CMICmnMIValueResult miValueResult(strType, miValueConst, bUseSpaces);
193 m_miValueTuple.Add(miValueResult, bUseSpaces);
194 }
195 }
196
197 return MIstatus::success;
Deepak Panickal6f9c4682014-05-16 10:51:01 +0000198}
199
200//++ ------------------------------------------------------------------------------------
Zachary Turner1d6af022014-11-17 18:06:21 +0000201// Details: The invoker requires this function. The command prepares a MI Record Result
202// for the work carried out in the Execute().
203// Type: Overridden.
204// Args: None.
205// Return: MIstatus::success - Functional succeeded.
206// MIstatus::failure - Functional failed.
207// Throws: None.
Deepak Panickal6f9c4682014-05-16 10:51:01 +0000208//--
Zachary Turner1d6af022014-11-17 18:06:21 +0000209bool
210CMICmdCmdDataEvaluateExpression::Acknowledge(void)
Deepak Panickal6f9c4682014-05-16 10:51:01 +0000211{
Zachary Turner1d6af022014-11-17 18:06:21 +0000212 if (m_bExpressionValid)
213 {
214 if (m_bEvaluatedExpression)
215 {
216 if (m_bCompositeVarType)
217 {
218 const CMICmnMIValueConst miValueConst(m_miValueTuple.GetString());
219 const CMICmnMIValueResult miValueResult("value", miValueConst);
220 const CMICmnMIResultRecord miRecordResult(m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Done, miValueResult);
221 m_miResultRecord = miRecordResult;
222 return MIstatus::success;
223 }
Deepak Panickald2499282014-08-08 16:47:42 +0000224
Zachary Turner1d6af022014-11-17 18:06:21 +0000225 if (m_bFoundInvalidChar)
226 {
227 const CMICmnMIValueConst miValueConst(
228 CMIUtilString::Format("Invalid character '%c' in expression", m_cExpressionInvalidChar));
229 const CMICmnMIValueResult miValueResult("msg", miValueConst);
230 const CMICmnMIResultRecord miRecordResult(m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Error, miValueResult);
231 m_miResultRecord = miRecordResult;
232 return MIstatus::success;
233 }
Deepak Panickal6f9c4682014-05-16 10:51:01 +0000234
Zachary Turner1d6af022014-11-17 18:06:21 +0000235 const CMICmnMIValueConst miValueConst(m_strValue);
236 const CMICmnMIValueResult miValueResult("value", miValueConst);
237 const CMICmnMIResultRecord miRecordResult(m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Done, miValueResult);
238 m_miResultRecord = miRecordResult;
239 return MIstatus::success;
240 }
Deepak Panickal6f9c4682014-05-16 10:51:01 +0000241
Zachary Turner1d6af022014-11-17 18:06:21 +0000242 const CMICmnMIValueConst miValueConst("Could not evaluate expression");
243 const CMICmnMIValueResult miValueResult("msg", miValueConst);
244 const CMICmnMIResultRecord miRecordResult(m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Error, miValueResult);
245 m_miResultRecord = miRecordResult;
246 return MIstatus::success;
247 }
248
249 const CMICmnMIValueConst miValueConst("Invalid expression");
250 const CMICmnMIValueResult miValueResult("msg", miValueConst);
251 const CMICmnMIResultRecord miRecordResult(m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Error, miValueResult);
252 m_miResultRecord = miRecordResult;
253
254 return MIstatus::success;
Deepak Panickal6f9c4682014-05-16 10:51:01 +0000255}
256
257//++ ------------------------------------------------------------------------------------
Zachary Turner1d6af022014-11-17 18:06:21 +0000258// Details: Required by the CMICmdFactory when registering *this command. The factory
259// calls this function to create an instance of *this command.
260// Type: Static method.
261// Args: None.
262// Return: CMICmdBase * - Pointer to a new command.
263// Throws: None.
Deepak Panickal6f9c4682014-05-16 10:51:01 +0000264//--
Zachary Turner1d6af022014-11-17 18:06:21 +0000265CMICmdBase *
266CMICmdCmdDataEvaluateExpression::CreateSelf(void)
Deepak Panickal6f9c4682014-05-16 10:51:01 +0000267{
Zachary Turner1d6af022014-11-17 18:06:21 +0000268 return new CMICmdCmdDataEvaluateExpression();
Deepak Panickal6f9c4682014-05-16 10:51:01 +0000269}
Deepak Panickal877569c2014-06-24 16:35:50 +0000270
Deepak Panickald2499282014-08-08 16:47:42 +0000271//++ ------------------------------------------------------------------------------------
Zachary Turner1d6af022014-11-17 18:06:21 +0000272// Details: Examine the expression string to see if it contains invalid characters.
273// Type: Method.
274// Args: vrExpr - (R) Expression string given to *this command.
275// vrwInvalidChar - (W) True = Invalid character found, false = nothing found.
276// Return: bool - True = Invalid character found, false = nothing found.
277// Throws: None.
Deepak Panickald2499282014-08-08 16:47:42 +0000278//--
Zachary Turner1d6af022014-11-17 18:06:21 +0000279bool
280CMICmdCmdDataEvaluateExpression::HaveInvalidCharacterInExpression(const CMIUtilString &vrExpr, MIchar &vrwInvalidChar)
Deepak Panickald2499282014-08-08 16:47:42 +0000281{
Zachary Turner1d6af022014-11-17 18:06:21 +0000282 bool bFoundInvalidCharInExpression = false;
283 vrwInvalidChar = 0x00;
Deepak Panickald2499282014-08-08 16:47:42 +0000284
Zachary Turner1d6af022014-11-17 18:06:21 +0000285 if (vrExpr.at(0) == '\\')
286 {
287 // Example: Mouse hover over "%5d" expression has \"%5d\" in it
288 bFoundInvalidCharInExpression = true;
289 vrwInvalidChar = '\\';
290 }
291
292 return bFoundInvalidCharInExpression;
Deepak Panickald2499282014-08-08 16:47:42 +0000293}
294
Deepak Panickal877569c2014-06-24 16:35:50 +0000295//---------------------------------------------------------------------------------------
296//---------------------------------------------------------------------------------------
297//---------------------------------------------------------------------------------------
298
299//++ ------------------------------------------------------------------------------------
Zachary Turner1d6af022014-11-17 18:06:21 +0000300// Details: CMICmdCmdDataDisassemble constructor.
301// Type: Method.
302// Args: None.
303// Return: None.
304// Throws: None.
Deepak Panickal877569c2014-06-24 16:35:50 +0000305//--
Zachary Turner1d6af022014-11-17 18:06:21 +0000306CMICmdCmdDataDisassemble::CMICmdCmdDataDisassemble(void)
307 : m_constStrArgThread("thread")
308 , m_constStrArgAddrStart("s")
309 , m_constStrArgAddrEnd("e")
310 , m_constStrArgConsume("--")
311 , m_constStrArgMode("mode")
312 , m_miValueList(true)
Deepak Panickal877569c2014-06-24 16:35:50 +0000313{
Zachary Turner1d6af022014-11-17 18:06:21 +0000314 // Command factory matches this name with that received from the stdin stream
315 m_strMiCmd = "data-disassemble";
316
317 // Required by the CMICmdFactory when registering *this command
318 m_pSelfCreatorFn = &CMICmdCmdDataDisassemble::CreateSelf;
Deepak Panickal877569c2014-06-24 16:35:50 +0000319}
320
321//++ ------------------------------------------------------------------------------------
Zachary Turner1d6af022014-11-17 18:06:21 +0000322// Details: CMICmdCmdDataDisassemble destructor.
323// Type: Overrideable.
324// Args: None.
325// Return: None.
326// Throws: None.
Deepak Panickal877569c2014-06-24 16:35:50 +0000327//--
Zachary Turner1d6af022014-11-17 18:06:21 +0000328CMICmdCmdDataDisassemble::~CMICmdCmdDataDisassemble(void)
Deepak Panickal877569c2014-06-24 16:35:50 +0000329{
330}
331
332//++ ------------------------------------------------------------------------------------
Zachary Turner1d6af022014-11-17 18:06:21 +0000333// Details: The invoker requires this function. The parses the command line options
334// arguments to extract values for each of those arguments.
335// Type: Overridden.
336// Args: None.
337// Return: MIstatus::success - Functional succeeded.
338// MIstatus::failure - Functional failed.
339// Throws: None.
Deepak Panickal877569c2014-06-24 16:35:50 +0000340//--
Zachary Turner1d6af022014-11-17 18:06:21 +0000341bool
342CMICmdCmdDataDisassemble::ParseArgs(void)
Deepak Panickal877569c2014-06-24 16:35:50 +0000343{
Zachary Turner1d6af022014-11-17 18:06:21 +0000344 bool bOk =
Hafiz Abid Qadeer54ba1242015-02-02 12:17:33 +0000345 m_setCmdArgs.Add(*(new CMICmdArgValOptionLong(m_constStrArgThread, false, true, CMICmdArgValListBase::eArgValType_Number, 1)));
Zachary Turner1d6af022014-11-17 18:06:21 +0000346 bOk = bOk &&
347 m_setCmdArgs.Add(
348 *(new CMICmdArgValOptionShort(m_constStrArgAddrStart, true, true, CMICmdArgValListBase::eArgValType_StringQuotedNumber, 1)));
349 bOk = bOk &&
350 m_setCmdArgs.Add(
351 *(new CMICmdArgValOptionShort(m_constStrArgAddrEnd, true, true, CMICmdArgValListBase::eArgValType_StringQuotedNumber, 1)));
352 bOk = bOk && m_setCmdArgs.Add(*(new CMICmdArgValConsume(m_constStrArgConsume, true)));
353 bOk = bOk && m_setCmdArgs.Add(*(new CMICmdArgValNumber(m_constStrArgMode, true, true)));
354 return (bOk && ParseValidateCmdOptions());
Deepak Panickal877569c2014-06-24 16:35:50 +0000355}
356
357//++ ------------------------------------------------------------------------------------
Zachary Turner1d6af022014-11-17 18:06:21 +0000358// Details: The invoker requires this function. The command does work in this function.
359// The command is likely to communicate with the LLDB SBDebugger in here.
360// Type: Overridden.
361// Args: None.
362// Return: MIstatus::success - Functional succeeded.
363// MIstatus::failure - Functional failed.
364// Throws: None.
Deepak Panickal877569c2014-06-24 16:35:50 +0000365//--
Zachary Turner1d6af022014-11-17 18:06:21 +0000366bool
367CMICmdCmdDataDisassemble::Execute(void)
Deepak Panickal877569c2014-06-24 16:35:50 +0000368{
Zachary Turner1d6af022014-11-17 18:06:21 +0000369 CMICMDBASE_GETOPTION(pArgThread, OptionLong, m_constStrArgThread);
370 CMICMDBASE_GETOPTION(pArgAddrStart, OptionShort, m_constStrArgAddrStart);
371 CMICMDBASE_GETOPTION(pArgAddrEnd, OptionShort, m_constStrArgAddrEnd);
372 CMICMDBASE_GETOPTION(pArgMode, Number, m_constStrArgMode);
Deepak Panickal877569c2014-06-24 16:35:50 +0000373
Zachary Turner1d6af022014-11-17 18:06:21 +0000374 // Retrieve the --thread option's thread ID (only 1)
375 MIuint64 nThreadId = UINT64_MAX;
Hafiz Abid Qadeer54ba1242015-02-02 12:17:33 +0000376 if (pArgThread->GetFound() && !pArgThread->GetExpectedOption<CMICmdArgValNumber, MIuint64>(nThreadId))
Zachary Turner1d6af022014-11-17 18:06:21 +0000377 {
378 SetError(CMIUtilString::Format(MIRSRC(IDS_CMD_ERR_THREAD_INVALID), m_cmdData.strMiCmd.c_str(), m_constStrArgThread.c_str()));
379 return MIstatus::failure;
380 }
381 CMIUtilString strAddrStart;
382 if (!pArgAddrStart->GetExpectedOption<CMICmdArgValString, CMIUtilString>(strAddrStart))
383 {
384 SetError(CMIUtilString::Format(MIRSRC(IDS_CMD_ERR_DISASM_ADDR_START_INVALID), m_cmdData.strMiCmd.c_str(),
385 m_constStrArgAddrStart.c_str()));
386 return MIstatus::failure;
387 }
388 MIint64 nAddrStart = 0;
389 if (!strAddrStart.ExtractNumber(nAddrStart))
390 {
391 SetError(CMIUtilString::Format(MIRSRC(IDS_CMD_ERR_DISASM_ADDR_START_INVALID), m_cmdData.strMiCmd.c_str(),
392 m_constStrArgAddrStart.c_str()));
393 return MIstatus::failure;
394 }
Deepak Panickal877569c2014-06-24 16:35:50 +0000395
Zachary Turner1d6af022014-11-17 18:06:21 +0000396 CMIUtilString strAddrEnd;
397 if (!pArgAddrEnd->GetExpectedOption<CMICmdArgValString, CMIUtilString>(strAddrEnd))
398 {
399 SetError(
400 CMIUtilString::Format(MIRSRC(IDS_CMD_ERR_DISASM_ADDR_END_INVALID), m_cmdData.strMiCmd.c_str(), m_constStrArgAddrEnd.c_str()));
401 return MIstatus::failure;
402 }
403 MIint64 nAddrEnd = 0;
404 if (!strAddrEnd.ExtractNumber(nAddrEnd))
405 {
406 SetError(
407 CMIUtilString::Format(MIRSRC(IDS_CMD_ERR_DISASM_ADDR_END_INVALID), m_cmdData.strMiCmd.c_str(), m_constStrArgAddrEnd.c_str()));
408 return MIstatus::failure;
409 }
410 const MIuint nDisasmMode = pArgMode->GetValue();
Deepak Panickal877569c2014-06-24 16:35:50 +0000411
Zachary Turner1d6af022014-11-17 18:06:21 +0000412 CMICmnLLDBDebugSessionInfo &rSessionInfo(CMICmnLLDBDebugSessionInfo::Instance());
Hafiz Abid Qadeer0d51c152015-02-03 10:05:54 +0000413 lldb::SBTarget sbTarget = rSessionInfo.GetTarget();
Zachary Turner1d6af022014-11-17 18:06:21 +0000414 lldb::addr_t lldbStartAddr = static_cast<lldb::addr_t>(nAddrStart);
Hafiz Abid Qadeer0d51c152015-02-03 10:05:54 +0000415 lldb::SBInstructionList instructions = sbTarget.ReadInstructions(lldb::SBAddress(lldbStartAddr, sbTarget), nAddrEnd - nAddrStart);
Zachary Turner1d6af022014-11-17 18:06:21 +0000416 const MIuint nInstructions = instructions.GetSize();
417 for (size_t i = 0; i < nInstructions; i++)
418 {
419 const MIchar *pUnknown = "??";
420 lldb::SBInstruction instrt = instructions.GetInstructionAtIndex(i);
Hafiz Abid Qadeer0d51c152015-02-03 10:05:54 +0000421 const MIchar *pStrMnemonic = instrt.GetMnemonic(sbTarget);
Zachary Turner1d6af022014-11-17 18:06:21 +0000422 pStrMnemonic = (pStrMnemonic != nullptr) ? pStrMnemonic : pUnknown;
423 lldb::SBAddress address = instrt.GetAddress();
Hafiz Abid Qadeer0d51c152015-02-03 10:05:54 +0000424 lldb::addr_t addr = address.GetLoadAddress(sbTarget);
Zachary Turner1d6af022014-11-17 18:06:21 +0000425 const MIchar *pFnName = address.GetFunction().GetName();
426 pFnName = (pFnName != nullptr) ? pFnName : pUnknown;
427 lldb::addr_t addrOffSet = address.GetOffset();
Hafiz Abid Qadeer0d51c152015-02-03 10:05:54 +0000428 const MIchar *pStrOperands = instrt.GetOperands(sbTarget);
Zachary Turner1d6af022014-11-17 18:06:21 +0000429 pStrOperands = (pStrOperands != nullptr) ? pStrOperands : pUnknown;
Deepak Panickal877569c2014-06-24 16:35:50 +0000430
Zachary Turner1d6af022014-11-17 18:06:21 +0000431 // MI "{address=\"0x%08llx\",func-name=\"%s\",offset=\"%lld\",inst=\"%s %s\"}"
432 const CMICmnMIValueConst miValueConst(CMIUtilString::Format("0x%08llx", addr));
433 const CMICmnMIValueResult miValueResult("address", miValueConst);
434 CMICmnMIValueTuple miValueTuple(miValueResult);
435 const CMICmnMIValueConst miValueConst2(pFnName);
436 const CMICmnMIValueResult miValueResult2("func-name", miValueConst2);
437 miValueTuple.Add(miValueResult2);
438 const CMICmnMIValueConst miValueConst3(CMIUtilString::Format("0x%lld", addrOffSet));
439 const CMICmnMIValueResult miValueResult3("offset", miValueConst3);
440 miValueTuple.Add(miValueResult3);
441 const CMICmnMIValueConst miValueConst4(CMIUtilString::Format("%s %s", pStrMnemonic, pStrOperands));
442 const CMICmnMIValueResult miValueResult4("inst", miValueConst4);
443 miValueTuple.Add(miValueResult4);
Deepak Panickal877569c2014-06-24 16:35:50 +0000444
Zachary Turner1d6af022014-11-17 18:06:21 +0000445 if (nDisasmMode == 1)
446 {
447 lldb::SBLineEntry lineEntry = address.GetLineEntry();
448 const MIuint nLine = lineEntry.GetLine();
449 const MIchar *pFileName = lineEntry.GetFileSpec().GetFilename();
450 pFileName = (pFileName != nullptr) ? pFileName : pUnknown;
451
452 // MI "src_and_asm_line={line=\"%u\",file=\"%s\",line_asm_insn=[ ]}"
453 const CMICmnMIValueConst miValueConst(CMIUtilString::Format("0x%u", nLine));
454 const CMICmnMIValueResult miValueResult("line", miValueConst);
455 CMICmnMIValueTuple miValueTuple2(miValueResult);
456 const CMICmnMIValueConst miValueConst2(pFileName);
457 const CMICmnMIValueResult miValueResult2("file", miValueConst2);
458 miValueTuple2.Add(miValueResult2);
459 const CMICmnMIValueList miValueList(miValueTuple);
460 const CMICmnMIValueResult miValueResult3("line_asm_insn", miValueList);
461 miValueTuple2.Add(miValueResult3);
462 const CMICmnMIValueResult miValueResult4("src_and_asm_line", miValueTuple2);
463 m_miValueList.Add(miValueResult4);
464 }
465 else
466 {
467 m_miValueList.Add(miValueTuple);
468 }
469 }
470
471 return MIstatus::success;
Deepak Panickal877569c2014-06-24 16:35:50 +0000472}
473
474//++ ------------------------------------------------------------------------------------
Zachary Turner1d6af022014-11-17 18:06:21 +0000475// Details: The invoker requires this function. The command prepares a MI Record Result
476// for the work carried out in the Execute().
477// Type: Overridden.
478// Args: None.
479// Return: MIstatus::success - Functional succeeded.
480// MIstatus::failure - Functional failed.
481// Throws: None.
Deepak Panickal877569c2014-06-24 16:35:50 +0000482//--
Zachary Turner1d6af022014-11-17 18:06:21 +0000483bool
484CMICmdCmdDataDisassemble::Acknowledge(void)
Deepak Panickal877569c2014-06-24 16:35:50 +0000485{
Zachary Turner1d6af022014-11-17 18:06:21 +0000486 const CMICmnMIValueResult miValueResult("asm_insns", m_miValueList);
487 const CMICmnMIResultRecord miRecordResult(m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Done, miValueResult);
488 m_miResultRecord = miRecordResult;
489
490 return MIstatus::success;
Deepak Panickal877569c2014-06-24 16:35:50 +0000491}
492
493//++ ------------------------------------------------------------------------------------
Zachary Turner1d6af022014-11-17 18:06:21 +0000494// Details: Required by the CMICmdFactory when registering *this command. The factory
495// calls this function to create an instance of *this command.
496// Type: Static method.
497// Args: None.
498// Return: CMICmdBase * - Pointer to a new command.
499// Throws: None.
Deepak Panickal877569c2014-06-24 16:35:50 +0000500//--
Zachary Turner1d6af022014-11-17 18:06:21 +0000501CMICmdBase *
502CMICmdCmdDataDisassemble::CreateSelf(void)
Deepak Panickal877569c2014-06-24 16:35:50 +0000503{
Zachary Turner1d6af022014-11-17 18:06:21 +0000504 return new CMICmdCmdDataDisassemble();
Deepak Panickal877569c2014-06-24 16:35:50 +0000505}
506
507//---------------------------------------------------------------------------------------
508//---------------------------------------------------------------------------------------
509//---------------------------------------------------------------------------------------
510
511//++ ------------------------------------------------------------------------------------
Zachary Turner1d6af022014-11-17 18:06:21 +0000512// Details: CMICmdCmdDataReadMemoryBytes constructor.
513// Type: Method.
514// Args: None.
515// Return: None.
516// Throws: None.
Deepak Panickal877569c2014-06-24 16:35:50 +0000517//--
Zachary Turner1d6af022014-11-17 18:06:21 +0000518CMICmdCmdDataReadMemoryBytes::CMICmdCmdDataReadMemoryBytes(void)
519 : m_constStrArgThread("thread")
520 , m_constStrArgByteOffset("o")
521 , m_constStrArgAddrStart("address")
522 , m_constStrArgNumBytes("count")
523 , m_pBufferMemory(nullptr)
524 , m_nAddrStart(0)
525 , m_nAddrNumBytesToRead(0)
526 , m_nAddrOffset(0)
Deepak Panickal877569c2014-06-24 16:35:50 +0000527{
Zachary Turner1d6af022014-11-17 18:06:21 +0000528 // Command factory matches this name with that received from the stdin stream
529 m_strMiCmd = "data-read-memory-bytes";
530
531 // Required by the CMICmdFactory when registering *this command
532 m_pSelfCreatorFn = &CMICmdCmdDataReadMemoryBytes::CreateSelf;
Deepak Panickal877569c2014-06-24 16:35:50 +0000533}
534
535//++ ------------------------------------------------------------------------------------
Zachary Turner1d6af022014-11-17 18:06:21 +0000536// Details: CMICmdCmdDataReadMemoryBytes destructor.
537// Type: Overrideable.
538// Args: None.
539// Return: None.
540// Throws: None.
Deepak Panickal877569c2014-06-24 16:35:50 +0000541//--
Zachary Turner1d6af022014-11-17 18:06:21 +0000542CMICmdCmdDataReadMemoryBytes::~CMICmdCmdDataReadMemoryBytes(void)
Deepak Panickal877569c2014-06-24 16:35:50 +0000543{
Zachary Turner1d6af022014-11-17 18:06:21 +0000544 if (m_pBufferMemory != nullptr)
545 {
546 delete[] m_pBufferMemory;
547 m_pBufferMemory = nullptr;
548 }
Deepak Panickal877569c2014-06-24 16:35:50 +0000549}
550
551//++ ------------------------------------------------------------------------------------
Zachary Turner1d6af022014-11-17 18:06:21 +0000552// Details: The invoker requires this function. The parses the command line options
553// arguments to extract values for each of those arguments.
554// Type: Overridden.
555// Args: None.
556// Return: MIstatus::success - Functional succeeded.
557// MIstatus::failure - Functional failed.
558// Throws: None.
Deepak Panickal877569c2014-06-24 16:35:50 +0000559//--
Zachary Turner1d6af022014-11-17 18:06:21 +0000560bool
561CMICmdCmdDataReadMemoryBytes::ParseArgs(void)
Deepak Panickal877569c2014-06-24 16:35:50 +0000562{
Zachary Turner1d6af022014-11-17 18:06:21 +0000563 bool bOk =
564 m_setCmdArgs.Add(*(new CMICmdArgValOptionLong(m_constStrArgThread, false, false, CMICmdArgValListBase::eArgValType_Number, 1)));
565 bOk =
566 bOk &&
567 m_setCmdArgs.Add(*(new CMICmdArgValOptionShort(m_constStrArgByteOffset, false, true, CMICmdArgValListBase::eArgValType_Number, 1)));
568 bOk = bOk && m_setCmdArgs.Add(*(new CMICmdArgValNumber(m_constStrArgAddrStart, true, true)));
569 bOk = bOk && m_setCmdArgs.Add(*(new CMICmdArgValNumber(m_constStrArgNumBytes, true, true)));
570 return (bOk && ParseValidateCmdOptions());
Deepak Panickal877569c2014-06-24 16:35:50 +0000571}
572
573//++ ------------------------------------------------------------------------------------
Zachary Turner1d6af022014-11-17 18:06:21 +0000574// Details: The invoker requires this function. The command does work in this function.
575// The command is likely to communicate with the LLDB SBDebugger in here.
576// Type: Overridden.
577// Args: None.
578// Return: MIstatus::success - Functional succeeded.
579// MIstatus::failure - Functional failed.
580// Throws: None.
Deepak Panickal877569c2014-06-24 16:35:50 +0000581//--
Zachary Turner1d6af022014-11-17 18:06:21 +0000582bool
583CMICmdCmdDataReadMemoryBytes::Execute(void)
Deepak Panickal877569c2014-06-24 16:35:50 +0000584{
Zachary Turner1d6af022014-11-17 18:06:21 +0000585 CMICMDBASE_GETOPTION(pArgAddrStart, Number, m_constStrArgAddrStart);
586 CMICMDBASE_GETOPTION(pArgAddrOffset, Number, m_constStrArgByteOffset);
587 CMICMDBASE_GETOPTION(pArgNumBytes, Number, m_constStrArgNumBytes);
Deepak Panickal877569c2014-06-24 16:35:50 +0000588
Zachary Turner1d6af022014-11-17 18:06:21 +0000589 const MIuint64 nAddrStart = pArgAddrStart->GetValue();
590 const MIuint64 nAddrNumBytes = pArgNumBytes->GetValue();
591 if (pArgAddrOffset->GetFound())
592 m_nAddrOffset = pArgAddrOffset->GetValue();
Deepak Panickal877569c2014-06-24 16:35:50 +0000593
Zachary Turner1d6af022014-11-17 18:06:21 +0000594 m_pBufferMemory = new MIuchar[nAddrNumBytes];
595 if (m_pBufferMemory == nullptr)
596 {
597 SetError(CMIUtilString::Format(MIRSRC(IDS_CMD_ERR_MEMORY_ALLOC_FAILURE), m_cmdData.strMiCmd.c_str(), nAddrNumBytes));
598 return MIstatus::failure;
599 }
600
601 CMICmnLLDBDebugSessionInfo &rSessionInfo(CMICmnLLDBDebugSessionInfo::Instance());
Hafiz Abid Qadeer0d51c152015-02-03 10:05:54 +0000602 lldb::SBProcess sbProcess = rSessionInfo.GetProcess();
Zachary Turner1d6af022014-11-17 18:06:21 +0000603 lldb::SBError error;
Hafiz Abid Qadeer0d51c152015-02-03 10:05:54 +0000604 const MIuint64 nReadBytes = sbProcess.ReadMemory(static_cast<lldb::addr_t>(nAddrStart), (void *)m_pBufferMemory, nAddrNumBytes, error);
Zachary Turner1d6af022014-11-17 18:06:21 +0000605 if (nReadBytes != nAddrNumBytes)
606 {
607 SetError(
608 CMIUtilString::Format(MIRSRC(IDS_CMD_ERR_LLDB_ERR_NOT_READ_WHOLE_BLK), m_cmdData.strMiCmd.c_str(), nAddrNumBytes, nAddrStart));
609 return MIstatus::failure;
610 }
611 if (error.Fail())
612 {
613 lldb::SBStream err;
614 const bool bOk = error.GetDescription(err);
615 MIunused(bOk);
616 SetError(CMIUtilString::Format(MIRSRC(IDS_CMD_ERR_LLDB_ERR_READ_MEM_BYTES), m_cmdData.strMiCmd.c_str(), nAddrNumBytes, nAddrStart,
617 err.GetData()));
618 return MIstatus::failure;
619 }
620
621 m_nAddrStart = nAddrStart;
622 m_nAddrNumBytesToRead = nAddrNumBytes;
623
624 return MIstatus::success;
Deepak Panickal877569c2014-06-24 16:35:50 +0000625}
626
627//++ ------------------------------------------------------------------------------------
Zachary Turner1d6af022014-11-17 18:06:21 +0000628// Details: The invoker requires this function. The command prepares a MI Record Result
629// for the work carried out in the Execute().
630// Type: Overridden.
631// Args: None.
632// Return: MIstatus::success - Functional succeeded.
633// MIstatus::failure - Functional failed.
634// Throws: None.
Deepak Panickal877569c2014-06-24 16:35:50 +0000635//--
Zachary Turner1d6af022014-11-17 18:06:21 +0000636bool
637CMICmdCmdDataReadMemoryBytes::Acknowledge(void)
Deepak Panickal877569c2014-06-24 16:35:50 +0000638{
Zachary Turner1d6af022014-11-17 18:06:21 +0000639 // MI: memory=[{begin=\"0x%08x\",offset=\"0x%08x\",end=\"0x%08x\",contents=\" \" }]"
640 const CMICmnMIValueConst miValueConst(CMIUtilString::Format("0x%08x", m_nAddrStart));
641 const CMICmnMIValueResult miValueResult("begin", miValueConst);
642 CMICmnMIValueTuple miValueTuple(miValueResult);
643 const CMICmnMIValueConst miValueConst2(CMIUtilString::Format("0x%08x", m_nAddrOffset));
644 const CMICmnMIValueResult miValueResult2("offset", miValueConst2);
645 miValueTuple.Add(miValueResult2);
646 const CMICmnMIValueConst miValueConst3(CMIUtilString::Format("0x%08x", m_nAddrStart + m_nAddrNumBytesToRead));
647 const CMICmnMIValueResult miValueResult3("end", miValueConst3);
648 miValueTuple.Add(miValueResult3);
Deepak Panickal877569c2014-06-24 16:35:50 +0000649
Zachary Turner1d6af022014-11-17 18:06:21 +0000650 // MI: contents=\" \"
651 CMIUtilString strContent;
652 strContent.reserve((m_nAddrNumBytesToRead << 1) + 1);
653 for (MIuint64 i = 0; i < m_nAddrNumBytesToRead; i++)
654 {
655 strContent += CMIUtilString::Format("%02x", m_pBufferMemory[i]);
656 }
657 const CMICmnMIValueConst miValueConst4(strContent);
658 const CMICmnMIValueResult miValueResult4("contents", miValueConst4);
659 miValueTuple.Add(miValueResult4);
660 const CMICmnMIValueList miValueList(miValueTuple);
661 const CMICmnMIValueResult miValueResult5("memory", miValueList);
662
663 const CMICmnMIResultRecord miRecordResult(m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Done, miValueResult5);
664 m_miResultRecord = miRecordResult;
665
666 return MIstatus::success;
Deepak Panickal877569c2014-06-24 16:35:50 +0000667}
668
669//++ ------------------------------------------------------------------------------------
Zachary Turner1d6af022014-11-17 18:06:21 +0000670// Details: Required by the CMICmdFactory when registering *this command. The factory
671// calls this function to create an instance of *this command.
672// Type: Static method.
673// Args: None.
674// Return: CMICmdBase * - Pointer to a new command.
675// Throws: None.
Deepak Panickal877569c2014-06-24 16:35:50 +0000676//--
Zachary Turner1d6af022014-11-17 18:06:21 +0000677CMICmdBase *
678CMICmdCmdDataReadMemoryBytes::CreateSelf(void)
Deepak Panickal877569c2014-06-24 16:35:50 +0000679{
Zachary Turner1d6af022014-11-17 18:06:21 +0000680 return new CMICmdCmdDataReadMemoryBytes();
Deepak Panickal877569c2014-06-24 16:35:50 +0000681}
682
683//---------------------------------------------------------------------------------------
684//---------------------------------------------------------------------------------------
685//---------------------------------------------------------------------------------------
686
687//++ ------------------------------------------------------------------------------------
Zachary Turner1d6af022014-11-17 18:06:21 +0000688// Details: CMICmdCmdDataReadMemory constructor.
689// Type: Method.
690// Args: None.
691// Return: None.
692// Throws: None.
Deepak Panickal877569c2014-06-24 16:35:50 +0000693//--
Zachary Turner1d6af022014-11-17 18:06:21 +0000694CMICmdCmdDataReadMemory::CMICmdCmdDataReadMemory(void)
Deepak Panickal877569c2014-06-24 16:35:50 +0000695{
Zachary Turner1d6af022014-11-17 18:06:21 +0000696 // Command factory matches this name with that received from the stdin stream
697 m_strMiCmd = "data-read-memory";
698
699 // Required by the CMICmdFactory when registering *this command
700 m_pSelfCreatorFn = &CMICmdCmdDataReadMemory::CreateSelf;
Deepak Panickal877569c2014-06-24 16:35:50 +0000701}
702
703//++ ------------------------------------------------------------------------------------
Zachary Turner1d6af022014-11-17 18:06:21 +0000704// Details: CMICmdCmdDataReadMemory destructor.
705// Type: Overrideable.
706// Args: None.
707// Return: None.
708// Throws: None.
Deepak Panickal877569c2014-06-24 16:35:50 +0000709//--
Zachary Turner1d6af022014-11-17 18:06:21 +0000710CMICmdCmdDataReadMemory::~CMICmdCmdDataReadMemory(void)
Deepak Panickal877569c2014-06-24 16:35:50 +0000711{
712}
713
714//++ ------------------------------------------------------------------------------------
Zachary Turner1d6af022014-11-17 18:06:21 +0000715// Details: The invoker requires this function. The command does work in this function.
716// The command is likely to communicate with the LLDB SBDebugger in here.
717// Type: Overridden.
718// Args: None.
719// Return: MIstatus::success - Functional succeeded.
720// MIstatus::failure - Functional failed.
721// Throws: None.
Deepak Panickal877569c2014-06-24 16:35:50 +0000722//--
Zachary Turner1d6af022014-11-17 18:06:21 +0000723bool
724CMICmdCmdDataReadMemory::Execute(void)
Deepak Panickal877569c2014-06-24 16:35:50 +0000725{
Zachary Turner1d6af022014-11-17 18:06:21 +0000726 // Do nothing - command deprecated use "data-read-memory-bytes" command
727 return MIstatus::success;
Deepak Panickal877569c2014-06-24 16:35:50 +0000728}
729
730//++ ------------------------------------------------------------------------------------
Zachary Turner1d6af022014-11-17 18:06:21 +0000731// Details: The invoker requires this function. The command prepares a MI Record Result
732// for the work carried out in the Execute().
733// Type: Overridden.
734// Args: None.
735// Return: MIstatus::success - Functional succeeded.
736// MIstatus::failure - Functional failed.
737// Throws: None.
Deepak Panickal877569c2014-06-24 16:35:50 +0000738//--
Zachary Turner1d6af022014-11-17 18:06:21 +0000739bool
740CMICmdCmdDataReadMemory::Acknowledge(void)
Deepak Panickal877569c2014-06-24 16:35:50 +0000741{
Zachary Turner1d6af022014-11-17 18:06:21 +0000742 // Command CMICmdCmdSupportListFeatures sends "data-read-memory-bytes" which causes this command not to be called
743 const CMICmnMIValueConst miValueConst(MIRSRC(IDS_CMD_ERR_NOT_IMPLEMENTED_DEPRECATED));
744 const CMICmnMIValueResult miValueResult("msg", miValueConst);
745 const CMICmnMIResultRecord miRecordResult(m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Error, miValueResult);
746 m_miResultRecord = miRecordResult;
747
748 return MIstatus::success;
Deepak Panickal877569c2014-06-24 16:35:50 +0000749}
750
751//++ ------------------------------------------------------------------------------------
Zachary Turner1d6af022014-11-17 18:06:21 +0000752// Details: Required by the CMICmdFactory when registering *this command. The factory
753// calls this function to create an instance of *this command.
754// Type: Static method.
755// Args: None.
756// Return: CMICmdBase * - Pointer to a new command.
757// Throws: None.
Deepak Panickal877569c2014-06-24 16:35:50 +0000758//--
Zachary Turner1d6af022014-11-17 18:06:21 +0000759CMICmdBase *
760CMICmdCmdDataReadMemory::CreateSelf(void)
Deepak Panickal877569c2014-06-24 16:35:50 +0000761{
Zachary Turner1d6af022014-11-17 18:06:21 +0000762 return new CMICmdCmdDataReadMemory();
Deepak Panickal877569c2014-06-24 16:35:50 +0000763}
764
765//---------------------------------------------------------------------------------------
766//---------------------------------------------------------------------------------------
767//---------------------------------------------------------------------------------------
768
769//++ ------------------------------------------------------------------------------------
Zachary Turner1d6af022014-11-17 18:06:21 +0000770// Details: CMICmdCmdDataListRegisterNames constructor.
771// Type: Method.
772// Args: None.
773// Return: None.
774// Throws: None.
Deepak Panickal877569c2014-06-24 16:35:50 +0000775//--
Zachary Turner1d6af022014-11-17 18:06:21 +0000776CMICmdCmdDataListRegisterNames::CMICmdCmdDataListRegisterNames(void)
777 : m_constStrArgThreadGroup("thread-group")
778 , m_constStrArgRegNo("regno")
779 , m_miValueList(true)
Deepak Panickal877569c2014-06-24 16:35:50 +0000780{
Zachary Turner1d6af022014-11-17 18:06:21 +0000781 // Command factory matches this name with that received from the stdin stream
782 m_strMiCmd = "data-list-register-names";
783
784 // Required by the CMICmdFactory when registering *this command
785 m_pSelfCreatorFn = &CMICmdCmdDataListRegisterNames::CreateSelf;
Deepak Panickal877569c2014-06-24 16:35:50 +0000786}
787
788//++ ------------------------------------------------------------------------------------
Zachary Turner1d6af022014-11-17 18:06:21 +0000789// Details: CMICmdCmdDataReadMemoryBytes destructor.
790// Type: Overrideable.
791// Args: None.
792// Return: None.
793// Throws: None.
Deepak Panickal877569c2014-06-24 16:35:50 +0000794//--
Zachary Turner1d6af022014-11-17 18:06:21 +0000795CMICmdCmdDataListRegisterNames::~CMICmdCmdDataListRegisterNames(void)
Deepak Panickal877569c2014-06-24 16:35:50 +0000796{
797}
798
799//++ ------------------------------------------------------------------------------------
Zachary Turner1d6af022014-11-17 18:06:21 +0000800// Details: The invoker requires this function. The parses the command line options
801// arguments to extract values for each of those arguments.
802// Type: Overridden.
803// Args: None.
804// Return: MIstatus::success - Functional succeeded.
805// MIstatus::failure - Functional failed.
806// Throws: None.
Deepak Panickal877569c2014-06-24 16:35:50 +0000807//--
Zachary Turner1d6af022014-11-17 18:06:21 +0000808bool
809CMICmdCmdDataListRegisterNames::ParseArgs(void)
Deepak Panickal877569c2014-06-24 16:35:50 +0000810{
Zachary Turner1d6af022014-11-17 18:06:21 +0000811 bool bOk = m_setCmdArgs.Add(
812 *(new CMICmdArgValOptionLong(m_constStrArgThreadGroup, false, false, CMICmdArgValListBase::eArgValType_ThreadGrp, 1)));
813 bOk = bOk && m_setCmdArgs.Add(*(new CMICmdArgValListOfN(m_constStrArgRegNo, false, false, CMICmdArgValListBase::eArgValType_Number)));
814 return (bOk && ParseValidateCmdOptions());
Deepak Panickal877569c2014-06-24 16:35:50 +0000815}
816
817//++ ------------------------------------------------------------------------------------
Zachary Turner1d6af022014-11-17 18:06:21 +0000818// Details: The invoker requires this function. The command does work in this function.
819// The command is likely to communicate with the LLDB SBDebugger in here.
820// Type: Overridden.
821// Args: None.
822// Return: MIstatus::success - Functional succeeded.
823// MIstatus::failure - Functional failed.
824// Throws: None.
Deepak Panickal877569c2014-06-24 16:35:50 +0000825//--
Zachary Turner1d6af022014-11-17 18:06:21 +0000826bool
827CMICmdCmdDataListRegisterNames::Execute(void)
Deepak Panickal877569c2014-06-24 16:35:50 +0000828{
Zachary Turner1d6af022014-11-17 18:06:21 +0000829 CMICmnLLDBDebugSessionInfo &rSessionInfo(CMICmnLLDBDebugSessionInfo::Instance());
Hafiz Abid Qadeer0d51c152015-02-03 10:05:54 +0000830 lldb::SBProcess sbProcess = rSessionInfo.GetProcess();
Hafiz Abid Qadeer6a814ad2015-02-05 14:57:07 +0000831 if (!sbProcess.IsValid())
Zachary Turner1d6af022014-11-17 18:06:21 +0000832 {
833 SetError(CMIUtilString::Format(MIRSRC(IDS_CMD_ERR_INVALID_PROCESS), m_cmdData.strMiCmd.c_str()));
834 return MIstatus::failure;
835 }
836
Hafiz Abid Qadeer0d51c152015-02-03 10:05:54 +0000837 lldb::SBThread thread = sbProcess.GetSelectedThread();
Zachary Turner1d6af022014-11-17 18:06:21 +0000838 lldb::SBFrame frame = thread.GetSelectedFrame();
839 lldb::SBValueList registers = frame.GetRegisters();
840 const MIuint nRegisters = registers.GetSize();
841 for (MIuint i = 0; i < nRegisters; i++)
842 {
843 lldb::SBValue value = registers.GetValueAtIndex(i);
844 const MIuint nRegChildren = value.GetNumChildren();
845 for (MIuint j = 0; j < nRegChildren; j++)
846 {
847 lldb::SBValue value2 = value.GetChildAtIndex(j);
848 if (value2.IsValid())
849 {
850 const CMICmnMIValueConst miValueConst(CMICmnLLDBUtilSBValue(value2).GetName());
851 m_miValueList.Add(miValueConst);
852 }
853 }
854 }
855
856 return MIstatus::success;
Deepak Panickal877569c2014-06-24 16:35:50 +0000857}
858
859//++ ------------------------------------------------------------------------------------
Zachary Turner1d6af022014-11-17 18:06:21 +0000860// Details: The invoker requires this function. The command prepares a MI Record Result
861// for the work carried out in the Execute().
862// Type: Overridden.
863// Args: None.
864// Return: MIstatus::success - Functional succeeded.
865// MIstatus::failure - Functional failed.
866// Throws: None.
Deepak Panickal877569c2014-06-24 16:35:50 +0000867//--
Zachary Turner1d6af022014-11-17 18:06:21 +0000868bool
869CMICmdCmdDataListRegisterNames::Acknowledge(void)
Deepak Panickal877569c2014-06-24 16:35:50 +0000870{
Zachary Turner1d6af022014-11-17 18:06:21 +0000871 const CMICmnMIValueResult miValueResult("register-names", m_miValueList);
872 const CMICmnMIResultRecord miRecordResult(m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Done, miValueResult);
873 m_miResultRecord = miRecordResult;
874
875 return MIstatus::success;
Deepak Panickal877569c2014-06-24 16:35:50 +0000876}
877
878//++ ------------------------------------------------------------------------------------
Zachary Turner1d6af022014-11-17 18:06:21 +0000879// Details: Required by the CMICmdFactory when registering *this command. The factory
880// calls this function to create an instance of *this command.
881// Type: Static method.
882// Args: None.
883// Return: CMICmdBase * - Pointer to a new command.
884// Throws: None.
Deepak Panickal877569c2014-06-24 16:35:50 +0000885//--
Zachary Turner1d6af022014-11-17 18:06:21 +0000886CMICmdBase *
887CMICmdCmdDataListRegisterNames::CreateSelf(void)
Deepak Panickal877569c2014-06-24 16:35:50 +0000888{
Zachary Turner1d6af022014-11-17 18:06:21 +0000889 return new CMICmdCmdDataListRegisterNames();
Deepak Panickal877569c2014-06-24 16:35:50 +0000890}
891
892//---------------------------------------------------------------------------------------
893//---------------------------------------------------------------------------------------
894//---------------------------------------------------------------------------------------
895
896//++ ------------------------------------------------------------------------------------
Zachary Turner1d6af022014-11-17 18:06:21 +0000897// Details: CMICmdCmdDataListRegisterValues constructor.
898// Type: Method.
899// Args: None.
900// Return: None.
901// Throws: None.
Deepak Panickal877569c2014-06-24 16:35:50 +0000902//--
Zachary Turner1d6af022014-11-17 18:06:21 +0000903CMICmdCmdDataListRegisterValues::CMICmdCmdDataListRegisterValues(void)
904 : m_constStrArgThread("thread")
905 , m_constStrArgSkip("skip-unavailable")
906 , m_constStrArgFormat("fmt")
907 , m_constStrArgRegNo("regno")
908 , m_miValueList(true)
Deepak Panickal877569c2014-06-24 16:35:50 +0000909{
Zachary Turner1d6af022014-11-17 18:06:21 +0000910 // Command factory matches this name with that received from the stdin stream
911 m_strMiCmd = "data-list-register-values";
912
913 // Required by the CMICmdFactory when registering *this command
914 m_pSelfCreatorFn = &CMICmdCmdDataListRegisterValues::CreateSelf;
Deepak Panickal877569c2014-06-24 16:35:50 +0000915}
916
917//++ ------------------------------------------------------------------------------------
Zachary Turner1d6af022014-11-17 18:06:21 +0000918// Details: CMICmdCmdDataListRegisterValues destructor.
919// Type: Overrideable.
920// Args: None.
921// Return: None.
922// Throws: None.
Deepak Panickal877569c2014-06-24 16:35:50 +0000923//--
Zachary Turner1d6af022014-11-17 18:06:21 +0000924CMICmdCmdDataListRegisterValues::~CMICmdCmdDataListRegisterValues(void)
Deepak Panickal877569c2014-06-24 16:35:50 +0000925{
926}
927
928//++ ------------------------------------------------------------------------------------
Zachary Turner1d6af022014-11-17 18:06:21 +0000929// Details: The invoker requires this function. The parses the command line options
930// arguments to extract values for each of those arguments.
931// Type: Overridden.
932// Args: None.
933// Return: MIstatus::success - Functional succeeded.
934// MIstatus::failure - Functional failed.
935// Throws: None.
Deepak Panickal877569c2014-06-24 16:35:50 +0000936//--
Zachary Turner1d6af022014-11-17 18:06:21 +0000937bool
938CMICmdCmdDataListRegisterValues::ParseArgs(void)
Deepak Panickal877569c2014-06-24 16:35:50 +0000939{
Zachary Turner1d6af022014-11-17 18:06:21 +0000940 bool bOk =
941 m_setCmdArgs.Add(*(new CMICmdArgValOptionLong(m_constStrArgThread, false, false, CMICmdArgValListBase::eArgValType_Number, 1)));
942 bOk = bOk && m_setCmdArgs.Add(*(new CMICmdArgValOptionLong(m_constStrArgSkip, false, false)));
943 bOk = bOk && m_setCmdArgs.Add(*(new CMICmdArgValString(m_constStrArgFormat, true, true)));
944 bOk = bOk && m_setCmdArgs.Add(*(new CMICmdArgValListOfN(m_constStrArgRegNo, false, true, CMICmdArgValListBase::eArgValType_Number)));
945 return (bOk && ParseValidateCmdOptions());
Deepak Panickal877569c2014-06-24 16:35:50 +0000946}
947
948//++ ------------------------------------------------------------------------------------
Zachary Turner1d6af022014-11-17 18:06:21 +0000949// Details: The invoker requires this function. The command does work in this function.
950// The command is likely to communicate with the LLDB SBDebugger in here.
951// Type: Overridden.
952// Args: None.
953// Return: MIstatus::success - Functional succeeded.
954// MIstatus::failure - Functional failed.
955// Throws: None.
Deepak Panickal877569c2014-06-24 16:35:50 +0000956//--
Zachary Turner1d6af022014-11-17 18:06:21 +0000957bool
958CMICmdCmdDataListRegisterValues::Execute(void)
Deepak Panickal877569c2014-06-24 16:35:50 +0000959{
Zachary Turner1d6af022014-11-17 18:06:21 +0000960 CMICMDBASE_GETOPTION(pArgFormat, String, m_constStrArgFormat);
961 CMICMDBASE_GETOPTION(pArgRegNo, ListOfN, m_constStrArgRegNo);
Deepak Panickal877569c2014-06-24 16:35:50 +0000962
Zachary Turner1d6af022014-11-17 18:06:21 +0000963 const CMIUtilString &rStrFormat(pArgFormat->GetValue());
964 if (rStrFormat.length() != 1)
965 {
966 SetError(CMIUtilString::Format(MIRSRC(IDS_CMD_ERR_INVALID_FORMAT_TYPE), m_cmdData.strMiCmd.c_str(), rStrFormat.c_str()));
967 return MIstatus::failure;
968 }
969 const CMICmnLLDBDebugSessionInfoVarObj::varFormat_e eFormat = CMICmnLLDBDebugSessionInfoVarObj::GetVarFormatForChar(rStrFormat[0]);
970 if (eFormat == CMICmnLLDBDebugSessionInfoVarObj::eVarFormat_Invalid)
971 {
972 SetError(CMIUtilString::Format(MIRSRC(IDS_CMD_ERR_INVALID_FORMAT_TYPE), m_cmdData.strMiCmd.c_str(), rStrFormat.c_str()));
973 return MIstatus::failure;
974 }
Deepak Panickal877569c2014-06-24 16:35:50 +0000975
Zachary Turner1d6af022014-11-17 18:06:21 +0000976 CMICmnLLDBDebugSessionInfo &rSessionInfo(CMICmnLLDBDebugSessionInfo::Instance());
Hafiz Abid Qadeer0d51c152015-02-03 10:05:54 +0000977 lldb::SBProcess sbProcess = rSessionInfo.GetProcess();
978 if (!sbProcess.IsValid())
Zachary Turner1d6af022014-11-17 18:06:21 +0000979 {
980 SetError(CMIUtilString::Format(MIRSRC(IDS_CMD_ERR_INVALID_PROCESS), m_cmdData.strMiCmd.c_str()));
981 return MIstatus::failure;
982 }
Deepak Panickal877569c2014-06-24 16:35:50 +0000983
Zachary Turner1d6af022014-11-17 18:06:21 +0000984 const CMICmdArgValListBase::VecArgObjPtr_t &rVecRegNo(pArgRegNo->GetExpectedOptions());
985 CMICmdArgValListBase::VecArgObjPtr_t::const_iterator it = rVecRegNo.begin();
986 while (it != rVecRegNo.end())
987 {
988 const CMICmdArgValNumber *pRegNo = static_cast<CMICmdArgValNumber *>(*it);
989 const MIuint nReg = pRegNo->GetValue();
990 lldb::SBValue regValue = GetRegister(nReg);
991 const CMIUtilString strRegValue(CMICmnLLDBDebugSessionInfoVarObj::GetValueStringFormatted(regValue, eFormat));
Deepak Panickal877569c2014-06-24 16:35:50 +0000992
Zachary Turner1d6af022014-11-17 18:06:21 +0000993 const CMICmnMIValueConst miValueConst(CMIUtilString::Format("%u", nReg));
994 const CMICmnMIValueResult miValueResult("number", miValueConst);
995 CMICmnMIValueTuple miValueTuple(miValueResult);
996 const CMICmnMIValueConst miValueConst2(strRegValue);
997 const CMICmnMIValueResult miValueResult2("value", miValueConst2);
998 miValueTuple.Add(miValueResult2);
999 m_miValueList.Add(miValueTuple);
1000
1001 // Next
1002 ++it;
1003 }
1004
1005 return MIstatus::success;
Deepak Panickal877569c2014-06-24 16:35:50 +00001006}
1007
1008//++ ------------------------------------------------------------------------------------
Zachary Turner1d6af022014-11-17 18:06:21 +00001009// Details: The invoker requires this function. The command prepares a MI Record Result
1010// for the work carried out in the Execute().
1011// Type: Overridden.
1012// Args: None.
1013// Return: MIstatus::success - Functional succeeded.
1014// MIstatus::failure - Functional failed.
1015// Throws: None.
Deepak Panickal877569c2014-06-24 16:35:50 +00001016//--
Zachary Turner1d6af022014-11-17 18:06:21 +00001017bool
1018CMICmdCmdDataListRegisterValues::Acknowledge(void)
Deepak Panickal877569c2014-06-24 16:35:50 +00001019{
Zachary Turner1d6af022014-11-17 18:06:21 +00001020 const CMICmnMIValueResult miValueResult("register-values", m_miValueList);
1021 const CMICmnMIResultRecord miRecordResult(m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Done, miValueResult);
1022 m_miResultRecord = miRecordResult;
1023
1024 return MIstatus::success;
Deepak Panickal877569c2014-06-24 16:35:50 +00001025}
1026
1027//++ ------------------------------------------------------------------------------------
Zachary Turner1d6af022014-11-17 18:06:21 +00001028// Details: Required by the CMICmdFactory when registering *this command. The factory
1029// calls this function to create an instance of *this command.
1030// Type: Static method.
1031// Args: None.
1032// Return: CMICmdBase * - Pointer to a new command.
1033// Throws: None.
Deepak Panickal877569c2014-06-24 16:35:50 +00001034//--
Zachary Turner1d6af022014-11-17 18:06:21 +00001035CMICmdBase *
1036CMICmdCmdDataListRegisterValues::CreateSelf(void)
Deepak Panickal877569c2014-06-24 16:35:50 +00001037{
Zachary Turner1d6af022014-11-17 18:06:21 +00001038 return new CMICmdCmdDataListRegisterValues();
Deepak Panickal877569c2014-06-24 16:35:50 +00001039}
1040
1041//++ ------------------------------------------------------------------------------------
Zachary Turner1d6af022014-11-17 18:06:21 +00001042// Details: Required by the CMICmdFactory when registering *this command. The factory
1043// calls this function to create an instance of *this command.
1044// Type: Method.
1045// Args: None.
1046// Return: lldb::SBValue - LLDB SBValue object.
1047// Throws: None.
Deepak Panickal877569c2014-06-24 16:35:50 +00001048//--
Zachary Turner1d6af022014-11-17 18:06:21 +00001049lldb::SBValue
1050CMICmdCmdDataListRegisterValues::GetRegister(const MIuint vRegisterIndex) const
Deepak Panickal877569c2014-06-24 16:35:50 +00001051{
Hafiz Abid Qadeer0d51c152015-02-03 10:05:54 +00001052 lldb::SBThread thread = CMICmnLLDBDebugSessionInfo::Instance().GetProcess().GetSelectedThread();
Zachary Turner1d6af022014-11-17 18:06:21 +00001053 lldb::SBFrame frame = thread.GetSelectedFrame();
1054 lldb::SBValueList registers = frame.GetRegisters();
1055 const MIuint nRegisters = registers.GetSize();
1056 for (MIuint i = 0; i < nRegisters; i++)
1057 {
1058 lldb::SBValue value = registers.GetValueAtIndex(i);
1059 const MIuint nRegChildren = value.GetNumChildren();
1060 if (nRegChildren > 0)
1061 {
1062 lldb::SBValue value2 = value.GetChildAtIndex(vRegisterIndex);
1063 if (value2.IsValid())
1064 {
1065 return value2;
1066 }
1067 }
1068 }
Deepak Panickal877569c2014-06-24 16:35:50 +00001069
Zachary Turner1d6af022014-11-17 18:06:21 +00001070 return lldb::SBValue();
Deepak Panickal877569c2014-06-24 16:35:50 +00001071}
1072
1073//---------------------------------------------------------------------------------------
1074//---------------------------------------------------------------------------------------
1075//---------------------------------------------------------------------------------------
1076
1077//++ ------------------------------------------------------------------------------------
Zachary Turner1d6af022014-11-17 18:06:21 +00001078// Details: CMICmdCmdDataListRegisterChanged constructor.
1079// Type: Method.
1080// Args: None.
1081// Return: None.
1082// Throws: None.
Deepak Panickal877569c2014-06-24 16:35:50 +00001083//--
Zachary Turner1d6af022014-11-17 18:06:21 +00001084CMICmdCmdDataListRegisterChanged::CMICmdCmdDataListRegisterChanged(void)
Deepak Panickal877569c2014-06-24 16:35:50 +00001085{
Zachary Turner1d6af022014-11-17 18:06:21 +00001086 // Command factory matches this name with that received from the stdin stream
1087 m_strMiCmd = "data-list-changed-registers";
1088
1089 // Required by the CMICmdFactory when registering *this command
1090 m_pSelfCreatorFn = &CMICmdCmdDataListRegisterChanged::CreateSelf;
Deepak Panickal877569c2014-06-24 16:35:50 +00001091}
1092
1093//++ ------------------------------------------------------------------------------------
Zachary Turner1d6af022014-11-17 18:06:21 +00001094// Details: CMICmdCmdDataListRegisterChanged destructor.
1095// Type: Overrideable.
1096// Args: None.
1097// Return: None.
1098// Throws: None.
Deepak Panickal877569c2014-06-24 16:35:50 +00001099//--
Zachary Turner1d6af022014-11-17 18:06:21 +00001100CMICmdCmdDataListRegisterChanged::~CMICmdCmdDataListRegisterChanged(void)
Deepak Panickal877569c2014-06-24 16:35:50 +00001101{
1102}
1103
1104//++ ------------------------------------------------------------------------------------
Zachary Turner1d6af022014-11-17 18:06:21 +00001105// Details: The invoker requires this function. The command does work in this function.
1106// The command is likely to communicate with the LLDB SBDebugger in here.
1107// Type: Overridden.
1108// Args: None.
1109// Return: MIstatus::success - Functional succeeded.
1110// MIstatus::failure - Functional failed.
1111// Throws: None.
Deepak Panickal877569c2014-06-24 16:35:50 +00001112//--
Zachary Turner1d6af022014-11-17 18:06:21 +00001113bool
1114CMICmdCmdDataListRegisterChanged::Execute(void)
Deepak Panickal877569c2014-06-24 16:35:50 +00001115{
Zachary Turner1d6af022014-11-17 18:06:21 +00001116 // Do nothing
1117
1118 return MIstatus::success;
Deepak Panickal877569c2014-06-24 16:35:50 +00001119}
1120
1121//++ ------------------------------------------------------------------------------------
Zachary Turner1d6af022014-11-17 18:06:21 +00001122// Details: The invoker requires this function. The command prepares a MI Record Result
1123// for the work carried out in the Execute().
1124// Type: Overridden.
1125// Args: None.
1126// Return: MIstatus::success - Functional succeeded.
1127// MIstatus::failure - Functional failed.
1128// Throws: None.
Deepak Panickal877569c2014-06-24 16:35:50 +00001129//--
Zachary Turner1d6af022014-11-17 18:06:21 +00001130bool
1131CMICmdCmdDataListRegisterChanged::Acknowledge(void)
Deepak Panickal877569c2014-06-24 16:35:50 +00001132{
Zachary Turner1d6af022014-11-17 18:06:21 +00001133 const CMICmnMIValueConst miValueConst(MIRSRC(IDS_WORD_NOT_IMPLEMENTED));
1134 const CMICmnMIValueResult miValueResult("msg", miValueConst);
1135 const CMICmnMIResultRecord miRecordResult(m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Error, miValueResult);
1136 m_miResultRecord = miRecordResult;
Deepak Panickal877569c2014-06-24 16:35:50 +00001137
Zachary Turner1d6af022014-11-17 18:06:21 +00001138 return MIstatus::success;
Deepak Panickal877569c2014-06-24 16:35:50 +00001139}
1140
1141//++ ------------------------------------------------------------------------------------
Zachary Turner1d6af022014-11-17 18:06:21 +00001142// Details: Required by the CMICmdFactory when registering *this command. The factory
1143// calls this function to create an instance of *this command.
1144// Type: Static method.
1145// Args: None.
1146// Return: CMICmdBase * - Pointer to a new command.
1147// Throws: None.
Deepak Panickal877569c2014-06-24 16:35:50 +00001148//--
Zachary Turner1d6af022014-11-17 18:06:21 +00001149CMICmdBase *
1150CMICmdCmdDataListRegisterChanged::CreateSelf(void)
Deepak Panickal877569c2014-06-24 16:35:50 +00001151{
Zachary Turner1d6af022014-11-17 18:06:21 +00001152 return new CMICmdCmdDataListRegisterChanged();
Deepak Panickal877569c2014-06-24 16:35:50 +00001153}
1154
1155//---------------------------------------------------------------------------------------
1156//---------------------------------------------------------------------------------------
1157//---------------------------------------------------------------------------------------
1158
1159//++ ------------------------------------------------------------------------------------
Zachary Turner1d6af022014-11-17 18:06:21 +00001160// Details: CMICmdCmdDataWriteMemoryBytes constructor.
1161// Type: Method.
1162// Args: None.
1163// Return: None.
1164// Throws: None.
Deepak Panickal877569c2014-06-24 16:35:50 +00001165//--
Zachary Turner1d6af022014-11-17 18:06:21 +00001166CMICmdCmdDataWriteMemoryBytes::CMICmdCmdDataWriteMemoryBytes(void)
1167 : m_constStrArgThread("thread")
1168 , m_constStrArgAddr("address")
1169 , m_constStrArgContents("contents")
1170 , m_constStrArgCount("count")
Deepak Panickal877569c2014-06-24 16:35:50 +00001171{
Zachary Turner1d6af022014-11-17 18:06:21 +00001172 // Command factory matches this name with that received from the stdin stream
1173 m_strMiCmd = "data-write-memory-bytes";
1174
1175 // Required by the CMICmdFactory when registering *this command
1176 m_pSelfCreatorFn = &CMICmdCmdDataWriteMemoryBytes::CreateSelf;
Deepak Panickal877569c2014-06-24 16:35:50 +00001177}
1178
1179//++ ------------------------------------------------------------------------------------
Zachary Turner1d6af022014-11-17 18:06:21 +00001180// Details: CMICmdCmdDataWriteMemoryBytes destructor.
1181// Type: Overrideable.
1182// Args: None.
1183// Return: None.
1184// Throws: None.
Deepak Panickal877569c2014-06-24 16:35:50 +00001185//--
Zachary Turner1d6af022014-11-17 18:06:21 +00001186CMICmdCmdDataWriteMemoryBytes::~CMICmdCmdDataWriteMemoryBytes(void)
Deepak Panickal877569c2014-06-24 16:35:50 +00001187{
1188}
1189
1190//++ ------------------------------------------------------------------------------------
Zachary Turner1d6af022014-11-17 18:06:21 +00001191// Details: The invoker requires this function. The parses the command line options
1192// arguments to extract values for each of those arguments.
1193// Type: Overridden.
1194// Args: None.
1195// Return: MIstatus::success - Functional succeeded.
1196// MIstatus::failure - Functional failed.
1197// Throws: None.
Deepak Panickal877569c2014-06-24 16:35:50 +00001198//--
Zachary Turner1d6af022014-11-17 18:06:21 +00001199bool
1200CMICmdCmdDataWriteMemoryBytes::ParseArgs(void)
Deepak Panickal877569c2014-06-24 16:35:50 +00001201{
Zachary Turner1d6af022014-11-17 18:06:21 +00001202 bool bOk =
1203 m_setCmdArgs.Add(*(new CMICmdArgValOptionLong(m_constStrArgThread, false, false, CMICmdArgValListBase::eArgValType_Number, 1)));
1204 bOk = bOk && m_setCmdArgs.Add(*(new CMICmdArgValString(m_constStrArgAddr, true, true, false, true)));
1205 bOk = bOk && m_setCmdArgs.Add(*(new CMICmdArgValString(m_constStrArgContents, true, true, true, true)));
1206 bOk = bOk && m_setCmdArgs.Add(*(new CMICmdArgValString(m_constStrArgCount, false, true, false, true)));
1207 return (bOk && ParseValidateCmdOptions());
Deepak Panickal877569c2014-06-24 16:35:50 +00001208}
1209
1210//++ ------------------------------------------------------------------------------------
Zachary Turner1d6af022014-11-17 18:06:21 +00001211// Details: The invoker requires this function. The command does work in this function.
1212// The command is likely to communicate with the LLDB SBDebugger in here.
1213// Type: Overridden.
1214// Args: None.
1215// Return: MIstatus::success - Functional succeeded.
1216// MIstatus::failure - Functional failed.
1217// Throws: None.
Deepak Panickal877569c2014-06-24 16:35:50 +00001218//--
Zachary Turner1d6af022014-11-17 18:06:21 +00001219bool
1220CMICmdCmdDataWriteMemoryBytes::Execute(void)
Deepak Panickal877569c2014-06-24 16:35:50 +00001221{
Zachary Turner1d6af022014-11-17 18:06:21 +00001222 // Do nothing - not reproduceable (yet) in Eclipse
1223 // CMICMDBASE_GETOPTION( pArgOffset, OptionShort, m_constStrArgOffset );
1224 // CMICMDBASE_GETOPTION( pArgAddr, String, m_constStrArgAddr );
1225 // CMICMDBASE_GETOPTION( pArgNumber, String, m_constStrArgNumber );
1226 // CMICMDBASE_GETOPTION( pArgContents, String, m_constStrArgContents );
1227 //
1228 // Numbers extracts as string types as they could be hex numbers
1229 // '&' is not recognised and so has to be removed
Deepak Panickal877569c2014-06-24 16:35:50 +00001230
Zachary Turner1d6af022014-11-17 18:06:21 +00001231 return MIstatus::success;
Deepak Panickal877569c2014-06-24 16:35:50 +00001232}
1233
1234//++ ------------------------------------------------------------------------------------
Zachary Turner1d6af022014-11-17 18:06:21 +00001235// Details: The invoker requires this function. The command prepares a MI Record Result
1236// for the work carried out in the Execute().
1237// Type: Overridden.
1238// Args: None.
1239// Return: MIstatus::success - Functional succeeded.
1240// MIstatus::failure - Functional failed.
1241// Throws: None.
Deepak Panickal877569c2014-06-24 16:35:50 +00001242//--
Zachary Turner1d6af022014-11-17 18:06:21 +00001243bool
1244CMICmdCmdDataWriteMemoryBytes::Acknowledge(void)
Deepak Panickal877569c2014-06-24 16:35:50 +00001245{
Zachary Turner1d6af022014-11-17 18:06:21 +00001246 const CMICmnMIValueConst miValueConst(MIRSRC(IDS_WORD_NOT_IMPLEMENTED));
1247 const CMICmnMIValueResult miValueResult("msg", miValueConst);
1248 const CMICmnMIResultRecord miRecordResult(m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Error, miValueResult);
1249 m_miResultRecord = miRecordResult;
Deepak Panickal877569c2014-06-24 16:35:50 +00001250
Zachary Turner1d6af022014-11-17 18:06:21 +00001251 return MIstatus::success;
Deepak Panickal877569c2014-06-24 16:35:50 +00001252}
1253
1254//++ ------------------------------------------------------------------------------------
Zachary Turner1d6af022014-11-17 18:06:21 +00001255// Details: Required by the CMICmdFactory when registering *this command. The factory
1256// calls this function to create an instance of *this command.
1257// Type: Static method.
1258// Args: None.
1259// Return: CMICmdBase * - Pointer to a new command.
1260// Throws: None.
Deepak Panickal877569c2014-06-24 16:35:50 +00001261//--
Zachary Turner1d6af022014-11-17 18:06:21 +00001262CMICmdBase *
1263CMICmdCmdDataWriteMemoryBytes::CreateSelf(void)
Deepak Panickal877569c2014-06-24 16:35:50 +00001264{
Zachary Turner1d6af022014-11-17 18:06:21 +00001265 return new CMICmdCmdDataWriteMemoryBytes();
Deepak Panickal877569c2014-06-24 16:35:50 +00001266}
1267
1268//---------------------------------------------------------------------------------------
1269//---------------------------------------------------------------------------------------
1270//---------------------------------------------------------------------------------------
1271
1272//++ ------------------------------------------------------------------------------------
Zachary Turner1d6af022014-11-17 18:06:21 +00001273// Details: CMICmdCmdDataWriteMemory constructor.
1274// Type: Method.
1275// Args: None.
1276// Return: None.
1277// Throws: None.
Deepak Panickal877569c2014-06-24 16:35:50 +00001278//--
Zachary Turner1d6af022014-11-17 18:06:21 +00001279CMICmdCmdDataWriteMemory::CMICmdCmdDataWriteMemory(void)
1280 : m_constStrArgThread("thread")
1281 , m_constStrArgOffset("o")
1282 , m_constStrArgAddr("address")
1283 , m_constStrArgD("d")
1284 , m_constStrArgNumber("a number")
1285 , m_constStrArgContents("contents")
1286 , m_nAddr(0)
1287 , m_nCount(0)
1288 , m_pBufferMemory(nullptr)
Deepak Panickal877569c2014-06-24 16:35:50 +00001289{
Zachary Turner1d6af022014-11-17 18:06:21 +00001290 // Command factory matches this name with that received from the stdin stream
1291 m_strMiCmd = "data-write-memory";
1292
1293 // Required by the CMICmdFactory when registering *this command
1294 m_pSelfCreatorFn = &CMICmdCmdDataWriteMemory::CreateSelf;
Deepak Panickal877569c2014-06-24 16:35:50 +00001295}
1296
1297//++ ------------------------------------------------------------------------------------
Zachary Turner1d6af022014-11-17 18:06:21 +00001298// Details: CMICmdCmdDataWriteMemory destructor.
1299// Type: Overrideable.
1300// Args: None.
1301// Return: None.
1302// Throws: None.
Deepak Panickal877569c2014-06-24 16:35:50 +00001303//--
Zachary Turner1d6af022014-11-17 18:06:21 +00001304CMICmdCmdDataWriteMemory::~CMICmdCmdDataWriteMemory(void)
Deepak Panickal877569c2014-06-24 16:35:50 +00001305{
Zachary Turner1d6af022014-11-17 18:06:21 +00001306 if (m_pBufferMemory != nullptr)
1307 {
1308 delete[] m_pBufferMemory;
1309 m_pBufferMemory = nullptr;
1310 }
Deepak Panickal877569c2014-06-24 16:35:50 +00001311}
1312
1313//++ ------------------------------------------------------------------------------------
Zachary Turner1d6af022014-11-17 18:06:21 +00001314// Details: The invoker requires this function. The parses the command line options
1315// arguments to extract values for each of those arguments.
1316// Type: Overridden.
1317// Args: None.
1318// Return: MIstatus::success - Functional succeeded.
1319// MIstatus::failure - Functional failed.
1320// Throws: None.
Deepak Panickal877569c2014-06-24 16:35:50 +00001321//--
Zachary Turner1d6af022014-11-17 18:06:21 +00001322bool
1323CMICmdCmdDataWriteMemory::ParseArgs(void)
Deepak Panickal877569c2014-06-24 16:35:50 +00001324{
Zachary Turner1d6af022014-11-17 18:06:21 +00001325 bool bOk =
1326 m_setCmdArgs.Add(*(new CMICmdArgValOptionLong(m_constStrArgThread, false, false, CMICmdArgValListBase::eArgValType_Number, 1)));
1327 bOk = bOk &&
1328 m_setCmdArgs.Add(*(new CMICmdArgValOptionShort(m_constStrArgOffset, false, true, CMICmdArgValListBase::eArgValType_Number, 1)));
1329 bOk = bOk && m_setCmdArgs.Add(*(new CMICmdArgValNumber(m_constStrArgAddr, true, true)));
1330 bOk = bOk && m_setCmdArgs.Add(*(new CMICmdArgValString(m_constStrArgD, true, true)));
1331 bOk = bOk && m_setCmdArgs.Add(*(new CMICmdArgValNumber(m_constStrArgNumber, true, true)));
1332 bOk = bOk && m_setCmdArgs.Add(*(new CMICmdArgValNumber(m_constStrArgContents, true, true)));
1333 return (bOk && ParseValidateCmdOptions());
Deepak Panickal877569c2014-06-24 16:35:50 +00001334}
1335
1336//++ ------------------------------------------------------------------------------------
Zachary Turner1d6af022014-11-17 18:06:21 +00001337// Details: The invoker requires this function. The command does work in this function.
1338// The command is likely to communicate with the LLDB SBDebugger in here.
1339// Type: Overridden.
1340// Args: None.
1341// Return: MIstatus::success - Functional succeeded.
1342// MIstatus::failure - Functional failed.
1343// Throws: None.
Deepak Panickal877569c2014-06-24 16:35:50 +00001344//--
Zachary Turner1d6af022014-11-17 18:06:21 +00001345bool
1346CMICmdCmdDataWriteMemory::Execute(void)
Deepak Panickal877569c2014-06-24 16:35:50 +00001347{
Zachary Turner1d6af022014-11-17 18:06:21 +00001348 CMICMDBASE_GETOPTION(pArgOffset, OptionShort, m_constStrArgOffset);
1349 CMICMDBASE_GETOPTION(pArgAddr, Number, m_constStrArgAddr);
1350 CMICMDBASE_GETOPTION(pArgNumber, Number, m_constStrArgNumber);
1351 CMICMDBASE_GETOPTION(pArgContents, Number, m_constStrArgContents);
Deepak Panickal877569c2014-06-24 16:35:50 +00001352
Zachary Turner1d6af022014-11-17 18:06:21 +00001353 MIuint nAddrOffset = 0;
1354 if (pArgOffset->GetFound() && !pArgOffset->GetExpectedOption<CMICmdArgValNumber, MIuint>(nAddrOffset))
1355 {
1356 SetError(CMIUtilString::Format(MIRSRC(IDS_CMD_ARGS_ERR_VALIDATION_INVALID), m_cmdData.strMiCmd.c_str(), m_constStrArgAddr.c_str()));
1357 return MIstatus::failure;
1358 }
1359 m_nAddr = pArgAddr->GetValue();
1360 m_nCount = pArgNumber->GetValue();
1361 const MIuint64 nValue = pArgContents->GetValue();
Deepak Panickal877569c2014-06-24 16:35:50 +00001362
Zachary Turner1d6af022014-11-17 18:06:21 +00001363 m_pBufferMemory = new MIuchar[m_nCount];
1364 if (m_pBufferMemory == nullptr)
1365 {
1366 SetError(CMIUtilString::Format(MIRSRC(IDS_CMD_ERR_MEMORY_ALLOC_FAILURE), m_cmdData.strMiCmd.c_str(), m_nCount));
1367 return MIstatus::failure;
1368 }
1369 *m_pBufferMemory = static_cast<MIchar>(nValue);
Deepak Panickal877569c2014-06-24 16:35:50 +00001370
Zachary Turner1d6af022014-11-17 18:06:21 +00001371 CMICmnLLDBDebugSessionInfo &rSessionInfo(CMICmnLLDBDebugSessionInfo::Instance());
Hafiz Abid Qadeer0d51c152015-02-03 10:05:54 +00001372 lldb::SBProcess sbProcess = rSessionInfo.GetProcess();
Zachary Turner1d6af022014-11-17 18:06:21 +00001373 lldb::SBError error;
1374 lldb::addr_t addr = static_cast<lldb::addr_t>(m_nAddr + nAddrOffset);
Hafiz Abid Qadeer0d51c152015-02-03 10:05:54 +00001375 const size_t nBytesWritten = sbProcess.WriteMemory(addr, (const void *)m_pBufferMemory, (size_t)m_nCount, error);
Zachary Turner1d6af022014-11-17 18:06:21 +00001376 if (nBytesWritten != static_cast<size_t>(m_nCount))
1377 {
1378 SetError(CMIUtilString::Format(MIRSRC(IDS_CMD_ERR_LLDB_ERR_NOT_WRITE_WHOLEBLK), m_cmdData.strMiCmd.c_str(), m_nCount, addr));
1379 return MIstatus::failure;
1380 }
1381 if (error.Fail())
1382 {
1383 lldb::SBStream err;
1384 const bool bOk = error.GetDescription(err);
1385 MIunused(bOk);
1386 SetError(
1387 CMIUtilString::Format(MIRSRC(IDS_CMD_ERR_LLDB_ERR_WRITE_MEM_BYTES), m_cmdData.strMiCmd.c_str(), m_nCount, addr, err.GetData()));
1388 return MIstatus::failure;
1389 }
1390
1391 return MIstatus::success;
Deepak Panickal877569c2014-06-24 16:35:50 +00001392}
1393
1394//++ ------------------------------------------------------------------------------------
Zachary Turner1d6af022014-11-17 18:06:21 +00001395// Details: The invoker requires this function. The command prepares a MI Record Result
1396// for the work carried out in the Execute().
1397// Type: Overridden.
1398// Args: None.
1399// Return: MIstatus::success - Functional succeeded.
1400// MIstatus::failure - Functional failed.
1401// Throws: None.
Deepak Panickal877569c2014-06-24 16:35:50 +00001402//--
Zachary Turner1d6af022014-11-17 18:06:21 +00001403bool
1404CMICmdCmdDataWriteMemory::Acknowledge(void)
Deepak Panickal877569c2014-06-24 16:35:50 +00001405{
Zachary Turner1d6af022014-11-17 18:06:21 +00001406 const CMICmnMIResultRecord miRecordResult(m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Done);
1407 m_miResultRecord = miRecordResult;
Deepak Panickal877569c2014-06-24 16:35:50 +00001408
Zachary Turner1d6af022014-11-17 18:06:21 +00001409 return MIstatus::success;
Deepak Panickal877569c2014-06-24 16:35:50 +00001410}
1411
1412//++ ------------------------------------------------------------------------------------
Zachary Turner1d6af022014-11-17 18:06:21 +00001413// Details: Required by the CMICmdFactory when registering *this command. The factory
1414// calls this function to create an instance of *this command.
1415// Type: Static method.
1416// Args: None.
1417// Return: CMICmdBase * - Pointer to a new command.
1418// Throws: None.
Deepak Panickal877569c2014-06-24 16:35:50 +00001419//--
Zachary Turner1d6af022014-11-17 18:06:21 +00001420CMICmdBase *
1421CMICmdCmdDataWriteMemory::CreateSelf(void)
Deepak Panickal877569c2014-06-24 16:35:50 +00001422{
Zachary Turner1d6af022014-11-17 18:06:21 +00001423 return new CMICmdCmdDataWriteMemory();
Deepak Panickal877569c2014-06-24 16:35:50 +00001424}