blob: 92e419073335e4e875e46c258123803f730ecabb [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());
Ilia K761a7a42015-02-06 18:10:30 +0000133 if (!value.IsValid() || value.GetError().Fail())
Zachary Turner1d6af022014-11-17 18:06:21 +0000134 value = frame.FindVariable(rExpression.c_str());
Ilia K761a7a42015-02-06 18:10:30 +0000135 const CMICmnLLDBUtilSBValue utilValue(value);
136 if (!utilValue.IsValid() || utilValue.IsValueUnknown())
Zachary Turner1d6af022014-11-17 18:06:21 +0000137 {
138 m_bEvaluatedExpression = false;
139 return MIstatus::success;
140 }
Zachary Turner1d6af022014-11-17 18:06:21 +0000141 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{
Ilia K761a7a42015-02-06 18:10:30 +0000282 static const std::string strInvalidCharacters(";#\\");
283 const size_t nInvalidCharacterOffset = vrExpr.find_first_of(strInvalidCharacters);
284 const bool bFoundInvalidCharInExpression = (nInvalidCharacterOffset != CMIUtilString::npos);
285 vrwInvalidChar = bFoundInvalidCharInExpression ? vrExpr[nInvalidCharacterOffset] : 0x00;
Zachary Turner1d6af022014-11-17 18:06:21 +0000286 return bFoundInvalidCharInExpression;
Deepak Panickald2499282014-08-08 16:47:42 +0000287}
288
Deepak Panickal877569c2014-06-24 16:35:50 +0000289//---------------------------------------------------------------------------------------
290//---------------------------------------------------------------------------------------
291//---------------------------------------------------------------------------------------
292
293//++ ------------------------------------------------------------------------------------
Zachary Turner1d6af022014-11-17 18:06:21 +0000294// Details: CMICmdCmdDataDisassemble constructor.
295// Type: Method.
296// Args: None.
297// Return: None.
298// Throws: None.
Deepak Panickal877569c2014-06-24 16:35:50 +0000299//--
Zachary Turner1d6af022014-11-17 18:06:21 +0000300CMICmdCmdDataDisassemble::CMICmdCmdDataDisassemble(void)
301 : m_constStrArgThread("thread")
302 , m_constStrArgAddrStart("s")
303 , m_constStrArgAddrEnd("e")
304 , m_constStrArgConsume("--")
305 , m_constStrArgMode("mode")
306 , m_miValueList(true)
Deepak Panickal877569c2014-06-24 16:35:50 +0000307{
Zachary Turner1d6af022014-11-17 18:06:21 +0000308 // Command factory matches this name with that received from the stdin stream
309 m_strMiCmd = "data-disassemble";
310
311 // Required by the CMICmdFactory when registering *this command
312 m_pSelfCreatorFn = &CMICmdCmdDataDisassemble::CreateSelf;
Deepak Panickal877569c2014-06-24 16:35:50 +0000313}
314
315//++ ------------------------------------------------------------------------------------
Zachary Turner1d6af022014-11-17 18:06:21 +0000316// Details: CMICmdCmdDataDisassemble destructor.
317// Type: Overrideable.
318// Args: None.
319// Return: None.
320// Throws: None.
Deepak Panickal877569c2014-06-24 16:35:50 +0000321//--
Zachary Turner1d6af022014-11-17 18:06:21 +0000322CMICmdCmdDataDisassemble::~CMICmdCmdDataDisassemble(void)
Deepak Panickal877569c2014-06-24 16:35:50 +0000323{
324}
325
326//++ ------------------------------------------------------------------------------------
Zachary Turner1d6af022014-11-17 18:06:21 +0000327// Details: The invoker requires this function. The parses the command line options
328// arguments to extract values for each of those arguments.
329// Type: Overridden.
330// Args: None.
331// Return: MIstatus::success - Functional succeeded.
332// MIstatus::failure - Functional failed.
333// Throws: None.
Deepak Panickal877569c2014-06-24 16:35:50 +0000334//--
Zachary Turner1d6af022014-11-17 18:06:21 +0000335bool
336CMICmdCmdDataDisassemble::ParseArgs(void)
Deepak Panickal877569c2014-06-24 16:35:50 +0000337{
Zachary Turner1d6af022014-11-17 18:06:21 +0000338 bool bOk =
Hafiz Abid Qadeer54ba1242015-02-02 12:17:33 +0000339 m_setCmdArgs.Add(*(new CMICmdArgValOptionLong(m_constStrArgThread, false, true, CMICmdArgValListBase::eArgValType_Number, 1)));
Zachary Turner1d6af022014-11-17 18:06:21 +0000340 bOk = bOk &&
341 m_setCmdArgs.Add(
342 *(new CMICmdArgValOptionShort(m_constStrArgAddrStart, true, true, CMICmdArgValListBase::eArgValType_StringQuotedNumber, 1)));
343 bOk = bOk &&
344 m_setCmdArgs.Add(
345 *(new CMICmdArgValOptionShort(m_constStrArgAddrEnd, true, true, CMICmdArgValListBase::eArgValType_StringQuotedNumber, 1)));
346 bOk = bOk && m_setCmdArgs.Add(*(new CMICmdArgValConsume(m_constStrArgConsume, true)));
347 bOk = bOk && m_setCmdArgs.Add(*(new CMICmdArgValNumber(m_constStrArgMode, true, true)));
348 return (bOk && ParseValidateCmdOptions());
Deepak Panickal877569c2014-06-24 16:35:50 +0000349}
350
351//++ ------------------------------------------------------------------------------------
Zachary Turner1d6af022014-11-17 18:06:21 +0000352// Details: The invoker requires this function. The command does work in this function.
353// The command is likely to communicate with the LLDB SBDebugger in here.
354// Type: Overridden.
355// Args: None.
356// Return: MIstatus::success - Functional succeeded.
357// MIstatus::failure - Functional failed.
358// Throws: None.
Deepak Panickal877569c2014-06-24 16:35:50 +0000359//--
Zachary Turner1d6af022014-11-17 18:06:21 +0000360bool
361CMICmdCmdDataDisassemble::Execute(void)
Deepak Panickal877569c2014-06-24 16:35:50 +0000362{
Zachary Turner1d6af022014-11-17 18:06:21 +0000363 CMICMDBASE_GETOPTION(pArgThread, OptionLong, m_constStrArgThread);
364 CMICMDBASE_GETOPTION(pArgAddrStart, OptionShort, m_constStrArgAddrStart);
365 CMICMDBASE_GETOPTION(pArgAddrEnd, OptionShort, m_constStrArgAddrEnd);
366 CMICMDBASE_GETOPTION(pArgMode, Number, m_constStrArgMode);
Deepak Panickal877569c2014-06-24 16:35:50 +0000367
Zachary Turner1d6af022014-11-17 18:06:21 +0000368 // Retrieve the --thread option's thread ID (only 1)
369 MIuint64 nThreadId = UINT64_MAX;
Hafiz Abid Qadeer54ba1242015-02-02 12:17:33 +0000370 if (pArgThread->GetFound() && !pArgThread->GetExpectedOption<CMICmdArgValNumber, MIuint64>(nThreadId))
Zachary Turner1d6af022014-11-17 18:06:21 +0000371 {
372 SetError(CMIUtilString::Format(MIRSRC(IDS_CMD_ERR_THREAD_INVALID), m_cmdData.strMiCmd.c_str(), m_constStrArgThread.c_str()));
373 return MIstatus::failure;
374 }
375 CMIUtilString strAddrStart;
376 if (!pArgAddrStart->GetExpectedOption<CMICmdArgValString, CMIUtilString>(strAddrStart))
377 {
378 SetError(CMIUtilString::Format(MIRSRC(IDS_CMD_ERR_DISASM_ADDR_START_INVALID), m_cmdData.strMiCmd.c_str(),
379 m_constStrArgAddrStart.c_str()));
380 return MIstatus::failure;
381 }
382 MIint64 nAddrStart = 0;
383 if (!strAddrStart.ExtractNumber(nAddrStart))
384 {
385 SetError(CMIUtilString::Format(MIRSRC(IDS_CMD_ERR_DISASM_ADDR_START_INVALID), m_cmdData.strMiCmd.c_str(),
386 m_constStrArgAddrStart.c_str()));
387 return MIstatus::failure;
388 }
Deepak Panickal877569c2014-06-24 16:35:50 +0000389
Zachary Turner1d6af022014-11-17 18:06:21 +0000390 CMIUtilString strAddrEnd;
391 if (!pArgAddrEnd->GetExpectedOption<CMICmdArgValString, CMIUtilString>(strAddrEnd))
392 {
393 SetError(
394 CMIUtilString::Format(MIRSRC(IDS_CMD_ERR_DISASM_ADDR_END_INVALID), m_cmdData.strMiCmd.c_str(), m_constStrArgAddrEnd.c_str()));
395 return MIstatus::failure;
396 }
397 MIint64 nAddrEnd = 0;
398 if (!strAddrEnd.ExtractNumber(nAddrEnd))
399 {
400 SetError(
401 CMIUtilString::Format(MIRSRC(IDS_CMD_ERR_DISASM_ADDR_END_INVALID), m_cmdData.strMiCmd.c_str(), m_constStrArgAddrEnd.c_str()));
402 return MIstatus::failure;
403 }
404 const MIuint nDisasmMode = pArgMode->GetValue();
Deepak Panickal877569c2014-06-24 16:35:50 +0000405
Zachary Turner1d6af022014-11-17 18:06:21 +0000406 CMICmnLLDBDebugSessionInfo &rSessionInfo(CMICmnLLDBDebugSessionInfo::Instance());
Hafiz Abid Qadeer0d51c152015-02-03 10:05:54 +0000407 lldb::SBTarget sbTarget = rSessionInfo.GetTarget();
Zachary Turner1d6af022014-11-17 18:06:21 +0000408 lldb::addr_t lldbStartAddr = static_cast<lldb::addr_t>(nAddrStart);
Hafiz Abid Qadeer0d51c152015-02-03 10:05:54 +0000409 lldb::SBInstructionList instructions = sbTarget.ReadInstructions(lldb::SBAddress(lldbStartAddr, sbTarget), nAddrEnd - nAddrStart);
Zachary Turner1d6af022014-11-17 18:06:21 +0000410 const MIuint nInstructions = instructions.GetSize();
411 for (size_t i = 0; i < nInstructions; i++)
412 {
413 const MIchar *pUnknown = "??";
414 lldb::SBInstruction instrt = instructions.GetInstructionAtIndex(i);
Hafiz Abid Qadeer0d51c152015-02-03 10:05:54 +0000415 const MIchar *pStrMnemonic = instrt.GetMnemonic(sbTarget);
Zachary Turner1d6af022014-11-17 18:06:21 +0000416 pStrMnemonic = (pStrMnemonic != nullptr) ? pStrMnemonic : pUnknown;
417 lldb::SBAddress address = instrt.GetAddress();
Hafiz Abid Qadeer0d51c152015-02-03 10:05:54 +0000418 lldb::addr_t addr = address.GetLoadAddress(sbTarget);
Zachary Turner1d6af022014-11-17 18:06:21 +0000419 const MIchar *pFnName = address.GetFunction().GetName();
420 pFnName = (pFnName != nullptr) ? pFnName : pUnknown;
421 lldb::addr_t addrOffSet = address.GetOffset();
Hafiz Abid Qadeer0d51c152015-02-03 10:05:54 +0000422 const MIchar *pStrOperands = instrt.GetOperands(sbTarget);
Zachary Turner1d6af022014-11-17 18:06:21 +0000423 pStrOperands = (pStrOperands != nullptr) ? pStrOperands : pUnknown;
Ilia Kb792be82015-02-06 12:43:05 +0000424 const size_t instrtSize = instrt.GetByteSize();
Deepak Panickal877569c2014-06-24 16:35:50 +0000425
Zachary Turner1d6af022014-11-17 18:06:21 +0000426 // MI "{address=\"0x%08llx\",func-name=\"%s\",offset=\"%lld\",inst=\"%s %s\"}"
427 const CMICmnMIValueConst miValueConst(CMIUtilString::Format("0x%08llx", addr));
428 const CMICmnMIValueResult miValueResult("address", miValueConst);
429 CMICmnMIValueTuple miValueTuple(miValueResult);
430 const CMICmnMIValueConst miValueConst2(pFnName);
431 const CMICmnMIValueResult miValueResult2("func-name", miValueConst2);
432 miValueTuple.Add(miValueResult2);
433 const CMICmnMIValueConst miValueConst3(CMIUtilString::Format("0x%lld", addrOffSet));
434 const CMICmnMIValueResult miValueResult3("offset", miValueConst3);
435 miValueTuple.Add(miValueResult3);
Ilia Kb792be82015-02-06 12:43:05 +0000436 const CMICmnMIValueConst miValueConst4(CMIUtilString::Format("%d", instrtSize));
437 const CMICmnMIValueResult miValueResult4("size", miValueConst4);
Zachary Turner1d6af022014-11-17 18:06:21 +0000438 miValueTuple.Add(miValueResult4);
Ilia Kb792be82015-02-06 12:43:05 +0000439 const CMICmnMIValueConst miValueConst5(CMIUtilString::Format("%s %s", pStrMnemonic, pStrOperands));
440 const CMICmnMIValueResult miValueResult5("inst", miValueConst5);
441 miValueTuple.Add(miValueResult5);
Deepak Panickal877569c2014-06-24 16:35:50 +0000442
Zachary Turner1d6af022014-11-17 18:06:21 +0000443 if (nDisasmMode == 1)
444 {
445 lldb::SBLineEntry lineEntry = address.GetLineEntry();
446 const MIuint nLine = lineEntry.GetLine();
447 const MIchar *pFileName = lineEntry.GetFileSpec().GetFilename();
448 pFileName = (pFileName != nullptr) ? pFileName : pUnknown;
449
450 // MI "src_and_asm_line={line=\"%u\",file=\"%s\",line_asm_insn=[ ]}"
451 const CMICmnMIValueConst miValueConst(CMIUtilString::Format("0x%u", nLine));
452 const CMICmnMIValueResult miValueResult("line", miValueConst);
453 CMICmnMIValueTuple miValueTuple2(miValueResult);
454 const CMICmnMIValueConst miValueConst2(pFileName);
455 const CMICmnMIValueResult miValueResult2("file", miValueConst2);
456 miValueTuple2.Add(miValueResult2);
457 const CMICmnMIValueList miValueList(miValueTuple);
458 const CMICmnMIValueResult miValueResult3("line_asm_insn", miValueList);
459 miValueTuple2.Add(miValueResult3);
460 const CMICmnMIValueResult miValueResult4("src_and_asm_line", miValueTuple2);
461 m_miValueList.Add(miValueResult4);
462 }
463 else
464 {
465 m_miValueList.Add(miValueTuple);
466 }
467 }
468
469 return MIstatus::success;
Deepak Panickal877569c2014-06-24 16:35:50 +0000470}
471
472//++ ------------------------------------------------------------------------------------
Zachary Turner1d6af022014-11-17 18:06:21 +0000473// Details: The invoker requires this function. The command prepares a MI Record Result
474// for the work carried out in the Execute().
475// Type: Overridden.
476// Args: None.
477// Return: MIstatus::success - Functional succeeded.
478// MIstatus::failure - Functional failed.
479// Throws: None.
Deepak Panickal877569c2014-06-24 16:35:50 +0000480//--
Zachary Turner1d6af022014-11-17 18:06:21 +0000481bool
482CMICmdCmdDataDisassemble::Acknowledge(void)
Deepak Panickal877569c2014-06-24 16:35:50 +0000483{
Zachary Turner1d6af022014-11-17 18:06:21 +0000484 const CMICmnMIValueResult miValueResult("asm_insns", m_miValueList);
485 const CMICmnMIResultRecord miRecordResult(m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Done, miValueResult);
486 m_miResultRecord = miRecordResult;
487
488 return MIstatus::success;
Deepak Panickal877569c2014-06-24 16:35:50 +0000489}
490
491//++ ------------------------------------------------------------------------------------
Zachary Turner1d6af022014-11-17 18:06:21 +0000492// Details: Required by the CMICmdFactory when registering *this command. The factory
493// calls this function to create an instance of *this command.
494// Type: Static method.
495// Args: None.
496// Return: CMICmdBase * - Pointer to a new command.
497// Throws: None.
Deepak Panickal877569c2014-06-24 16:35:50 +0000498//--
Zachary Turner1d6af022014-11-17 18:06:21 +0000499CMICmdBase *
500CMICmdCmdDataDisassemble::CreateSelf(void)
Deepak Panickal877569c2014-06-24 16:35:50 +0000501{
Zachary Turner1d6af022014-11-17 18:06:21 +0000502 return new CMICmdCmdDataDisassemble();
Deepak Panickal877569c2014-06-24 16:35:50 +0000503}
504
505//---------------------------------------------------------------------------------------
506//---------------------------------------------------------------------------------------
507//---------------------------------------------------------------------------------------
508
509//++ ------------------------------------------------------------------------------------
Zachary Turner1d6af022014-11-17 18:06:21 +0000510// Details: CMICmdCmdDataReadMemoryBytes constructor.
511// Type: Method.
512// Args: None.
513// Return: None.
514// Throws: None.
Deepak Panickal877569c2014-06-24 16:35:50 +0000515//--
Zachary Turner1d6af022014-11-17 18:06:21 +0000516CMICmdCmdDataReadMemoryBytes::CMICmdCmdDataReadMemoryBytes(void)
517 : m_constStrArgThread("thread")
518 , m_constStrArgByteOffset("o")
519 , m_constStrArgAddrStart("address")
520 , m_constStrArgNumBytes("count")
521 , m_pBufferMemory(nullptr)
522 , m_nAddrStart(0)
523 , m_nAddrNumBytesToRead(0)
524 , m_nAddrOffset(0)
Deepak Panickal877569c2014-06-24 16:35:50 +0000525{
Zachary Turner1d6af022014-11-17 18:06:21 +0000526 // Command factory matches this name with that received from the stdin stream
527 m_strMiCmd = "data-read-memory-bytes";
528
529 // Required by the CMICmdFactory when registering *this command
530 m_pSelfCreatorFn = &CMICmdCmdDataReadMemoryBytes::CreateSelf;
Deepak Panickal877569c2014-06-24 16:35:50 +0000531}
532
533//++ ------------------------------------------------------------------------------------
Zachary Turner1d6af022014-11-17 18:06:21 +0000534// Details: CMICmdCmdDataReadMemoryBytes destructor.
535// Type: Overrideable.
536// Args: None.
537// Return: None.
538// Throws: None.
Deepak Panickal877569c2014-06-24 16:35:50 +0000539//--
Zachary Turner1d6af022014-11-17 18:06:21 +0000540CMICmdCmdDataReadMemoryBytes::~CMICmdCmdDataReadMemoryBytes(void)
Deepak Panickal877569c2014-06-24 16:35:50 +0000541{
Zachary Turner1d6af022014-11-17 18:06:21 +0000542 if (m_pBufferMemory != nullptr)
543 {
544 delete[] m_pBufferMemory;
545 m_pBufferMemory = nullptr;
546 }
Deepak Panickal877569c2014-06-24 16:35:50 +0000547}
548
549//++ ------------------------------------------------------------------------------------
Zachary Turner1d6af022014-11-17 18:06:21 +0000550// Details: The invoker requires this function. The parses the command line options
551// arguments to extract values for each of those arguments.
552// Type: Overridden.
553// Args: None.
554// Return: MIstatus::success - Functional succeeded.
555// MIstatus::failure - Functional failed.
556// Throws: None.
Deepak Panickal877569c2014-06-24 16:35:50 +0000557//--
Zachary Turner1d6af022014-11-17 18:06:21 +0000558bool
559CMICmdCmdDataReadMemoryBytes::ParseArgs(void)
Deepak Panickal877569c2014-06-24 16:35:50 +0000560{
Zachary Turner1d6af022014-11-17 18:06:21 +0000561 bool bOk =
562 m_setCmdArgs.Add(*(new CMICmdArgValOptionLong(m_constStrArgThread, false, false, CMICmdArgValListBase::eArgValType_Number, 1)));
563 bOk =
564 bOk &&
565 m_setCmdArgs.Add(*(new CMICmdArgValOptionShort(m_constStrArgByteOffset, false, true, CMICmdArgValListBase::eArgValType_Number, 1)));
566 bOk = bOk && m_setCmdArgs.Add(*(new CMICmdArgValNumber(m_constStrArgAddrStart, true, true)));
567 bOk = bOk && m_setCmdArgs.Add(*(new CMICmdArgValNumber(m_constStrArgNumBytes, true, true)));
568 return (bOk && ParseValidateCmdOptions());
Deepak Panickal877569c2014-06-24 16:35:50 +0000569}
570
571//++ ------------------------------------------------------------------------------------
Zachary Turner1d6af022014-11-17 18:06:21 +0000572// Details: The invoker requires this function. The command does work in this function.
573// The command is likely to communicate with the LLDB SBDebugger in here.
574// Type: Overridden.
575// Args: None.
576// Return: MIstatus::success - Functional succeeded.
577// MIstatus::failure - Functional failed.
578// Throws: None.
Deepak Panickal877569c2014-06-24 16:35:50 +0000579//--
Zachary Turner1d6af022014-11-17 18:06:21 +0000580bool
581CMICmdCmdDataReadMemoryBytes::Execute(void)
Deepak Panickal877569c2014-06-24 16:35:50 +0000582{
Zachary Turner1d6af022014-11-17 18:06:21 +0000583 CMICMDBASE_GETOPTION(pArgAddrStart, Number, m_constStrArgAddrStart);
584 CMICMDBASE_GETOPTION(pArgAddrOffset, Number, m_constStrArgByteOffset);
585 CMICMDBASE_GETOPTION(pArgNumBytes, Number, m_constStrArgNumBytes);
Deepak Panickal877569c2014-06-24 16:35:50 +0000586
Zachary Turner1d6af022014-11-17 18:06:21 +0000587 const MIuint64 nAddrStart = pArgAddrStart->GetValue();
588 const MIuint64 nAddrNumBytes = pArgNumBytes->GetValue();
589 if (pArgAddrOffset->GetFound())
590 m_nAddrOffset = pArgAddrOffset->GetValue();
Deepak Panickal877569c2014-06-24 16:35:50 +0000591
Zachary Turner1d6af022014-11-17 18:06:21 +0000592 m_pBufferMemory = new MIuchar[nAddrNumBytes];
593 if (m_pBufferMemory == nullptr)
594 {
595 SetError(CMIUtilString::Format(MIRSRC(IDS_CMD_ERR_MEMORY_ALLOC_FAILURE), m_cmdData.strMiCmd.c_str(), nAddrNumBytes));
596 return MIstatus::failure;
597 }
598
599 CMICmnLLDBDebugSessionInfo &rSessionInfo(CMICmnLLDBDebugSessionInfo::Instance());
Hafiz Abid Qadeer0d51c152015-02-03 10:05:54 +0000600 lldb::SBProcess sbProcess = rSessionInfo.GetProcess();
Zachary Turner1d6af022014-11-17 18:06:21 +0000601 lldb::SBError error;
Hafiz Abid Qadeer0d51c152015-02-03 10:05:54 +0000602 const MIuint64 nReadBytes = sbProcess.ReadMemory(static_cast<lldb::addr_t>(nAddrStart), (void *)m_pBufferMemory, nAddrNumBytes, error);
Zachary Turner1d6af022014-11-17 18:06:21 +0000603 if (nReadBytes != nAddrNumBytes)
604 {
605 SetError(
606 CMIUtilString::Format(MIRSRC(IDS_CMD_ERR_LLDB_ERR_NOT_READ_WHOLE_BLK), m_cmdData.strMiCmd.c_str(), nAddrNumBytes, nAddrStart));
607 return MIstatus::failure;
608 }
609 if (error.Fail())
610 {
611 lldb::SBStream err;
612 const bool bOk = error.GetDescription(err);
613 MIunused(bOk);
614 SetError(CMIUtilString::Format(MIRSRC(IDS_CMD_ERR_LLDB_ERR_READ_MEM_BYTES), m_cmdData.strMiCmd.c_str(), nAddrNumBytes, nAddrStart,
615 err.GetData()));
616 return MIstatus::failure;
617 }
618
619 m_nAddrStart = nAddrStart;
620 m_nAddrNumBytesToRead = nAddrNumBytes;
621
622 return MIstatus::success;
Deepak Panickal877569c2014-06-24 16:35:50 +0000623}
624
625//++ ------------------------------------------------------------------------------------
Zachary Turner1d6af022014-11-17 18:06:21 +0000626// Details: The invoker requires this function. The command prepares a MI Record Result
627// for the work carried out in the Execute().
628// Type: Overridden.
629// Args: None.
630// Return: MIstatus::success - Functional succeeded.
631// MIstatus::failure - Functional failed.
632// Throws: None.
Deepak Panickal877569c2014-06-24 16:35:50 +0000633//--
Zachary Turner1d6af022014-11-17 18:06:21 +0000634bool
635CMICmdCmdDataReadMemoryBytes::Acknowledge(void)
Deepak Panickal877569c2014-06-24 16:35:50 +0000636{
Zachary Turner1d6af022014-11-17 18:06:21 +0000637 // MI: memory=[{begin=\"0x%08x\",offset=\"0x%08x\",end=\"0x%08x\",contents=\" \" }]"
638 const CMICmnMIValueConst miValueConst(CMIUtilString::Format("0x%08x", m_nAddrStart));
639 const CMICmnMIValueResult miValueResult("begin", miValueConst);
640 CMICmnMIValueTuple miValueTuple(miValueResult);
641 const CMICmnMIValueConst miValueConst2(CMIUtilString::Format("0x%08x", m_nAddrOffset));
642 const CMICmnMIValueResult miValueResult2("offset", miValueConst2);
643 miValueTuple.Add(miValueResult2);
644 const CMICmnMIValueConst miValueConst3(CMIUtilString::Format("0x%08x", m_nAddrStart + m_nAddrNumBytesToRead));
645 const CMICmnMIValueResult miValueResult3("end", miValueConst3);
646 miValueTuple.Add(miValueResult3);
Deepak Panickal877569c2014-06-24 16:35:50 +0000647
Zachary Turner1d6af022014-11-17 18:06:21 +0000648 // MI: contents=\" \"
649 CMIUtilString strContent;
650 strContent.reserve((m_nAddrNumBytesToRead << 1) + 1);
651 for (MIuint64 i = 0; i < m_nAddrNumBytesToRead; i++)
652 {
653 strContent += CMIUtilString::Format("%02x", m_pBufferMemory[i]);
654 }
655 const CMICmnMIValueConst miValueConst4(strContent);
656 const CMICmnMIValueResult miValueResult4("contents", miValueConst4);
657 miValueTuple.Add(miValueResult4);
658 const CMICmnMIValueList miValueList(miValueTuple);
659 const CMICmnMIValueResult miValueResult5("memory", miValueList);
660
661 const CMICmnMIResultRecord miRecordResult(m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Done, miValueResult5);
662 m_miResultRecord = miRecordResult;
663
664 return MIstatus::success;
Deepak Panickal877569c2014-06-24 16:35:50 +0000665}
666
667//++ ------------------------------------------------------------------------------------
Zachary Turner1d6af022014-11-17 18:06:21 +0000668// Details: Required by the CMICmdFactory when registering *this command. The factory
669// calls this function to create an instance of *this command.
670// Type: Static method.
671// Args: None.
672// Return: CMICmdBase * - Pointer to a new command.
673// Throws: None.
Deepak Panickal877569c2014-06-24 16:35:50 +0000674//--
Zachary Turner1d6af022014-11-17 18:06:21 +0000675CMICmdBase *
676CMICmdCmdDataReadMemoryBytes::CreateSelf(void)
Deepak Panickal877569c2014-06-24 16:35:50 +0000677{
Zachary Turner1d6af022014-11-17 18:06:21 +0000678 return new CMICmdCmdDataReadMemoryBytes();
Deepak Panickal877569c2014-06-24 16:35:50 +0000679}
680
681//---------------------------------------------------------------------------------------
682//---------------------------------------------------------------------------------------
683//---------------------------------------------------------------------------------------
684
685//++ ------------------------------------------------------------------------------------
Zachary Turner1d6af022014-11-17 18:06:21 +0000686// Details: CMICmdCmdDataReadMemory constructor.
687// Type: Method.
688// Args: None.
689// Return: None.
690// Throws: None.
Deepak Panickal877569c2014-06-24 16:35:50 +0000691//--
Zachary Turner1d6af022014-11-17 18:06:21 +0000692CMICmdCmdDataReadMemory::CMICmdCmdDataReadMemory(void)
Deepak Panickal877569c2014-06-24 16:35:50 +0000693{
Zachary Turner1d6af022014-11-17 18:06:21 +0000694 // Command factory matches this name with that received from the stdin stream
695 m_strMiCmd = "data-read-memory";
696
697 // Required by the CMICmdFactory when registering *this command
698 m_pSelfCreatorFn = &CMICmdCmdDataReadMemory::CreateSelf;
Deepak Panickal877569c2014-06-24 16:35:50 +0000699}
700
701//++ ------------------------------------------------------------------------------------
Zachary Turner1d6af022014-11-17 18:06:21 +0000702// Details: CMICmdCmdDataReadMemory destructor.
703// Type: Overrideable.
704// Args: None.
705// Return: None.
706// Throws: None.
Deepak Panickal877569c2014-06-24 16:35:50 +0000707//--
Zachary Turner1d6af022014-11-17 18:06:21 +0000708CMICmdCmdDataReadMemory::~CMICmdCmdDataReadMemory(void)
Deepak Panickal877569c2014-06-24 16:35:50 +0000709{
710}
711
712//++ ------------------------------------------------------------------------------------
Zachary Turner1d6af022014-11-17 18:06:21 +0000713// Details: The invoker requires this function. The command does work in this function.
714// The command is likely to communicate with the LLDB SBDebugger in here.
715// Type: Overridden.
716// Args: None.
717// Return: MIstatus::success - Functional succeeded.
718// MIstatus::failure - Functional failed.
719// Throws: None.
Deepak Panickal877569c2014-06-24 16:35:50 +0000720//--
Zachary Turner1d6af022014-11-17 18:06:21 +0000721bool
722CMICmdCmdDataReadMemory::Execute(void)
Deepak Panickal877569c2014-06-24 16:35:50 +0000723{
Zachary Turner1d6af022014-11-17 18:06:21 +0000724 // Do nothing - command deprecated use "data-read-memory-bytes" command
725 return MIstatus::success;
Deepak Panickal877569c2014-06-24 16:35:50 +0000726}
727
728//++ ------------------------------------------------------------------------------------
Zachary Turner1d6af022014-11-17 18:06:21 +0000729// Details: The invoker requires this function. The command prepares a MI Record Result
730// for the work carried out in the Execute().
731// Type: Overridden.
732// Args: None.
733// Return: MIstatus::success - Functional succeeded.
734// MIstatus::failure - Functional failed.
735// Throws: None.
Deepak Panickal877569c2014-06-24 16:35:50 +0000736//--
Zachary Turner1d6af022014-11-17 18:06:21 +0000737bool
738CMICmdCmdDataReadMemory::Acknowledge(void)
Deepak Panickal877569c2014-06-24 16:35:50 +0000739{
Zachary Turner1d6af022014-11-17 18:06:21 +0000740 // Command CMICmdCmdSupportListFeatures sends "data-read-memory-bytes" which causes this command not to be called
741 const CMICmnMIValueConst miValueConst(MIRSRC(IDS_CMD_ERR_NOT_IMPLEMENTED_DEPRECATED));
742 const CMICmnMIValueResult miValueResult("msg", miValueConst);
743 const CMICmnMIResultRecord miRecordResult(m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Error, miValueResult);
744 m_miResultRecord = miRecordResult;
745
746 return MIstatus::success;
Deepak Panickal877569c2014-06-24 16:35:50 +0000747}
748
749//++ ------------------------------------------------------------------------------------
Zachary Turner1d6af022014-11-17 18:06:21 +0000750// Details: Required by the CMICmdFactory when registering *this command. The factory
751// calls this function to create an instance of *this command.
752// Type: Static method.
753// Args: None.
754// Return: CMICmdBase * - Pointer to a new command.
755// Throws: None.
Deepak Panickal877569c2014-06-24 16:35:50 +0000756//--
Zachary Turner1d6af022014-11-17 18:06:21 +0000757CMICmdBase *
758CMICmdCmdDataReadMemory::CreateSelf(void)
Deepak Panickal877569c2014-06-24 16:35:50 +0000759{
Zachary Turner1d6af022014-11-17 18:06:21 +0000760 return new CMICmdCmdDataReadMemory();
Deepak Panickal877569c2014-06-24 16:35:50 +0000761}
762
763//---------------------------------------------------------------------------------------
764//---------------------------------------------------------------------------------------
765//---------------------------------------------------------------------------------------
766
767//++ ------------------------------------------------------------------------------------
Zachary Turner1d6af022014-11-17 18:06:21 +0000768// Details: CMICmdCmdDataListRegisterNames constructor.
769// Type: Method.
770// Args: None.
771// Return: None.
772// Throws: None.
Deepak Panickal877569c2014-06-24 16:35:50 +0000773//--
Zachary Turner1d6af022014-11-17 18:06:21 +0000774CMICmdCmdDataListRegisterNames::CMICmdCmdDataListRegisterNames(void)
775 : m_constStrArgThreadGroup("thread-group")
776 , m_constStrArgRegNo("regno")
777 , m_miValueList(true)
Deepak Panickal877569c2014-06-24 16:35:50 +0000778{
Zachary Turner1d6af022014-11-17 18:06:21 +0000779 // Command factory matches this name with that received from the stdin stream
780 m_strMiCmd = "data-list-register-names";
781
782 // Required by the CMICmdFactory when registering *this command
783 m_pSelfCreatorFn = &CMICmdCmdDataListRegisterNames::CreateSelf;
Deepak Panickal877569c2014-06-24 16:35:50 +0000784}
785
786//++ ------------------------------------------------------------------------------------
Zachary Turner1d6af022014-11-17 18:06:21 +0000787// Details: CMICmdCmdDataReadMemoryBytes destructor.
788// Type: Overrideable.
789// Args: None.
790// Return: None.
791// Throws: None.
Deepak Panickal877569c2014-06-24 16:35:50 +0000792//--
Zachary Turner1d6af022014-11-17 18:06:21 +0000793CMICmdCmdDataListRegisterNames::~CMICmdCmdDataListRegisterNames(void)
Deepak Panickal877569c2014-06-24 16:35:50 +0000794{
795}
796
797//++ ------------------------------------------------------------------------------------
Zachary Turner1d6af022014-11-17 18:06:21 +0000798// Details: The invoker requires this function. The parses the command line options
799// arguments to extract values for each of those arguments.
800// Type: Overridden.
801// Args: None.
802// Return: MIstatus::success - Functional succeeded.
803// MIstatus::failure - Functional failed.
804// Throws: None.
Deepak Panickal877569c2014-06-24 16:35:50 +0000805//--
Zachary Turner1d6af022014-11-17 18:06:21 +0000806bool
807CMICmdCmdDataListRegisterNames::ParseArgs(void)
Deepak Panickal877569c2014-06-24 16:35:50 +0000808{
Zachary Turner1d6af022014-11-17 18:06:21 +0000809 bool bOk = m_setCmdArgs.Add(
810 *(new CMICmdArgValOptionLong(m_constStrArgThreadGroup, false, false, CMICmdArgValListBase::eArgValType_ThreadGrp, 1)));
811 bOk = bOk && m_setCmdArgs.Add(*(new CMICmdArgValListOfN(m_constStrArgRegNo, false, false, CMICmdArgValListBase::eArgValType_Number)));
812 return (bOk && ParseValidateCmdOptions());
Deepak Panickal877569c2014-06-24 16:35:50 +0000813}
814
815//++ ------------------------------------------------------------------------------------
Zachary Turner1d6af022014-11-17 18:06:21 +0000816// Details: The invoker requires this function. The command does work in this function.
817// The command is likely to communicate with the LLDB SBDebugger in here.
818// Type: Overridden.
819// Args: None.
820// Return: MIstatus::success - Functional succeeded.
821// MIstatus::failure - Functional failed.
822// Throws: None.
Deepak Panickal877569c2014-06-24 16:35:50 +0000823//--
Zachary Turner1d6af022014-11-17 18:06:21 +0000824bool
825CMICmdCmdDataListRegisterNames::Execute(void)
Deepak Panickal877569c2014-06-24 16:35:50 +0000826{
Ilia Kb792be82015-02-06 12:43:05 +0000827 CMICMDBASE_GETOPTION(pArgRegNo, ListOfN, m_constStrArgRegNo);
828
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
Ilia Kb792be82015-02-06 12:43:05 +0000837 const CMICmdArgValListBase::VecArgObjPtr_t &rVecRegNo(pArgRegNo->GetExpectedOptions());
838 if (!rVecRegNo.empty())
Zachary Turner1d6af022014-11-17 18:06:21 +0000839 {
Ilia Kb792be82015-02-06 12:43:05 +0000840 // List of required registers
841 CMICmdArgValListBase::VecArgObjPtr_t::const_iterator it = rVecRegNo.begin();
842 while (it != rVecRegNo.end())
Zachary Turner1d6af022014-11-17 18:06:21 +0000843 {
Ilia Kb792be82015-02-06 12:43:05 +0000844 const CMICmdArgValNumber *pRegNo = static_cast<CMICmdArgValNumber *>(*it);
845 const MIuint nRegIndex = pRegNo->GetValue();
846 lldb::SBValue regValue = GetRegister(nRegIndex);
847 if (regValue.IsValid())
Zachary Turner1d6af022014-11-17 18:06:21 +0000848 {
Ilia Kb792be82015-02-06 12:43:05 +0000849 const CMICmnMIValueConst miValueConst(CMICmnLLDBUtilSBValue(regValue).GetName());
Zachary Turner1d6af022014-11-17 18:06:21 +0000850 m_miValueList.Add(miValueConst);
851 }
Ilia Kb792be82015-02-06 12:43:05 +0000852
853 // Next
854 ++it;
855 }
856 }
857 else
858 {
859 // List of all registers
860 lldb::SBThread thread = sbProcess.GetSelectedThread();
861 lldb::SBFrame frame = thread.GetSelectedFrame();
862 lldb::SBValueList registers = frame.GetRegisters();
863 const MIuint nRegisters = registers.GetSize();
864 for (MIuint i = 0; i < nRegisters; i++)
865 {
866 lldb::SBValue value = registers.GetValueAtIndex(i);
867 const MIuint nRegChildren = value.GetNumChildren();
868 for (MIuint j = 0; j < nRegChildren; j++)
869 {
870 lldb::SBValue regValue = value.GetChildAtIndex(j);
871 if (regValue.IsValid())
872 {
873 const CMICmnMIValueConst miValueConst(CMICmnLLDBUtilSBValue(regValue).GetName());
874 const bool bOk = m_miValueList.Add(miValueConst);
875 if (!bOk)
876 return MIstatus::failure;
877 }
878 }
Zachary Turner1d6af022014-11-17 18:06:21 +0000879 }
880 }
881
882 return MIstatus::success;
Deepak Panickal877569c2014-06-24 16:35:50 +0000883}
884
885//++ ------------------------------------------------------------------------------------
Zachary Turner1d6af022014-11-17 18:06:21 +0000886// Details: The invoker requires this function. The command prepares a MI Record Result
887// for the work carried out in the Execute().
888// Type: Overridden.
889// Args: None.
890// Return: MIstatus::success - Functional succeeded.
891// MIstatus::failure - Functional failed.
892// Throws: None.
Deepak Panickal877569c2014-06-24 16:35:50 +0000893//--
Zachary Turner1d6af022014-11-17 18:06:21 +0000894bool
895CMICmdCmdDataListRegisterNames::Acknowledge(void)
Deepak Panickal877569c2014-06-24 16:35:50 +0000896{
Zachary Turner1d6af022014-11-17 18:06:21 +0000897 const CMICmnMIValueResult miValueResult("register-names", m_miValueList);
898 const CMICmnMIResultRecord miRecordResult(m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Done, miValueResult);
899 m_miResultRecord = miRecordResult;
900
901 return MIstatus::success;
Deepak Panickal877569c2014-06-24 16:35:50 +0000902}
903
904//++ ------------------------------------------------------------------------------------
Zachary Turner1d6af022014-11-17 18:06:21 +0000905// Details: Required by the CMICmdFactory when registering *this command. The factory
906// calls this function to create an instance of *this command.
907// Type: Static method.
908// Args: None.
909// Return: CMICmdBase * - Pointer to a new command.
910// Throws: None.
Deepak Panickal877569c2014-06-24 16:35:50 +0000911//--
Zachary Turner1d6af022014-11-17 18:06:21 +0000912CMICmdBase *
913CMICmdCmdDataListRegisterNames::CreateSelf(void)
Deepak Panickal877569c2014-06-24 16:35:50 +0000914{
Zachary Turner1d6af022014-11-17 18:06:21 +0000915 return new CMICmdCmdDataListRegisterNames();
Deepak Panickal877569c2014-06-24 16:35:50 +0000916}
917
Ilia Kb792be82015-02-06 12:43:05 +0000918//++ ------------------------------------------------------------------------------------
919// Details: Required by the CMICmdFactory when registering *this command. The factory
920// calls this function to create an instance of *this command.
921// Type: Method.
922// Args: None.
923// Return: lldb::SBValue - LLDB SBValue object.
924// Throws: None.
925//--
926lldb::SBValue
927CMICmdCmdDataListRegisterNames::GetRegister(const MIuint vRegisterIndex) const
928{
929 lldb::SBThread thread = CMICmnLLDBDebugSessionInfo::Instance().GetProcess().GetSelectedThread();
930 lldb::SBFrame frame = thread.GetSelectedFrame();
931 lldb::SBValueList registers = frame.GetRegisters();
932 const MIuint nRegisters = registers.GetSize();
933 MIuint nRegisterIndex(vRegisterIndex);
934 for (MIuint i = 0; i < nRegisters; i++)
935 {
936 lldb::SBValue value = registers.GetValueAtIndex(i);
937 const MIuint nRegChildren = value.GetNumChildren();
938 if (nRegisterIndex >= nRegChildren)
939 {
940 nRegisterIndex -= nRegChildren;
941 continue;
942 }
943
944 lldb::SBValue value2 = value.GetChildAtIndex(nRegisterIndex);
945 if (value2.IsValid())
946 {
947 return value2;
948 }
949 }
950
951 return lldb::SBValue();
952}
953
Deepak Panickal877569c2014-06-24 16:35:50 +0000954//---------------------------------------------------------------------------------------
955//---------------------------------------------------------------------------------------
956//---------------------------------------------------------------------------------------
957
958//++ ------------------------------------------------------------------------------------
Zachary Turner1d6af022014-11-17 18:06:21 +0000959// Details: CMICmdCmdDataListRegisterValues constructor.
960// Type: Method.
961// Args: None.
962// Return: None.
963// Throws: None.
Deepak Panickal877569c2014-06-24 16:35:50 +0000964//--
Zachary Turner1d6af022014-11-17 18:06:21 +0000965CMICmdCmdDataListRegisterValues::CMICmdCmdDataListRegisterValues(void)
966 : m_constStrArgThread("thread")
967 , m_constStrArgSkip("skip-unavailable")
968 , m_constStrArgFormat("fmt")
969 , m_constStrArgRegNo("regno")
970 , m_miValueList(true)
Deepak Panickal877569c2014-06-24 16:35:50 +0000971{
Zachary Turner1d6af022014-11-17 18:06:21 +0000972 // Command factory matches this name with that received from the stdin stream
973 m_strMiCmd = "data-list-register-values";
974
975 // Required by the CMICmdFactory when registering *this command
976 m_pSelfCreatorFn = &CMICmdCmdDataListRegisterValues::CreateSelf;
Deepak Panickal877569c2014-06-24 16:35:50 +0000977}
978
979//++ ------------------------------------------------------------------------------------
Zachary Turner1d6af022014-11-17 18:06:21 +0000980// Details: CMICmdCmdDataListRegisterValues destructor.
981// Type: Overrideable.
982// Args: None.
983// Return: None.
984// Throws: None.
Deepak Panickal877569c2014-06-24 16:35:50 +0000985//--
Zachary Turner1d6af022014-11-17 18:06:21 +0000986CMICmdCmdDataListRegisterValues::~CMICmdCmdDataListRegisterValues(void)
Deepak Panickal877569c2014-06-24 16:35:50 +0000987{
988}
989
990//++ ------------------------------------------------------------------------------------
Zachary Turner1d6af022014-11-17 18:06:21 +0000991// Details: The invoker requires this function. The parses the command line options
992// arguments to extract values for each of those arguments.
993// Type: Overridden.
994// Args: None.
995// Return: MIstatus::success - Functional succeeded.
996// MIstatus::failure - Functional failed.
997// Throws: None.
Deepak Panickal877569c2014-06-24 16:35:50 +0000998//--
Zachary Turner1d6af022014-11-17 18:06:21 +0000999bool
1000CMICmdCmdDataListRegisterValues::ParseArgs(void)
Deepak Panickal877569c2014-06-24 16:35:50 +00001001{
Zachary Turner1d6af022014-11-17 18:06:21 +00001002 bool bOk =
1003 m_setCmdArgs.Add(*(new CMICmdArgValOptionLong(m_constStrArgThread, false, false, CMICmdArgValListBase::eArgValType_Number, 1)));
1004 bOk = bOk && m_setCmdArgs.Add(*(new CMICmdArgValOptionLong(m_constStrArgSkip, false, false)));
1005 bOk = bOk && m_setCmdArgs.Add(*(new CMICmdArgValString(m_constStrArgFormat, true, true)));
1006 bOk = bOk && m_setCmdArgs.Add(*(new CMICmdArgValListOfN(m_constStrArgRegNo, false, true, CMICmdArgValListBase::eArgValType_Number)));
1007 return (bOk && ParseValidateCmdOptions());
Deepak Panickal877569c2014-06-24 16:35:50 +00001008}
1009
1010//++ ------------------------------------------------------------------------------------
Zachary Turner1d6af022014-11-17 18:06:21 +00001011// Details: The invoker requires this function. The command does work in this function.
1012// The command is likely to communicate with the LLDB SBDebugger in here.
1013// Type: Overridden.
1014// Args: None.
1015// Return: MIstatus::success - Functional succeeded.
1016// MIstatus::failure - Functional failed.
1017// Throws: None.
Deepak Panickal877569c2014-06-24 16:35:50 +00001018//--
Zachary Turner1d6af022014-11-17 18:06:21 +00001019bool
1020CMICmdCmdDataListRegisterValues::Execute(void)
Deepak Panickal877569c2014-06-24 16:35:50 +00001021{
Zachary Turner1d6af022014-11-17 18:06:21 +00001022 CMICMDBASE_GETOPTION(pArgFormat, String, m_constStrArgFormat);
1023 CMICMDBASE_GETOPTION(pArgRegNo, ListOfN, m_constStrArgRegNo);
Deepak Panickal877569c2014-06-24 16:35:50 +00001024
Zachary Turner1d6af022014-11-17 18:06:21 +00001025 const CMIUtilString &rStrFormat(pArgFormat->GetValue());
1026 if (rStrFormat.length() != 1)
1027 {
1028 SetError(CMIUtilString::Format(MIRSRC(IDS_CMD_ERR_INVALID_FORMAT_TYPE), m_cmdData.strMiCmd.c_str(), rStrFormat.c_str()));
1029 return MIstatus::failure;
1030 }
1031 const CMICmnLLDBDebugSessionInfoVarObj::varFormat_e eFormat = CMICmnLLDBDebugSessionInfoVarObj::GetVarFormatForChar(rStrFormat[0]);
1032 if (eFormat == CMICmnLLDBDebugSessionInfoVarObj::eVarFormat_Invalid)
1033 {
1034 SetError(CMIUtilString::Format(MIRSRC(IDS_CMD_ERR_INVALID_FORMAT_TYPE), m_cmdData.strMiCmd.c_str(), rStrFormat.c_str()));
1035 return MIstatus::failure;
1036 }
Deepak Panickal877569c2014-06-24 16:35:50 +00001037
Zachary Turner1d6af022014-11-17 18:06:21 +00001038 CMICmnLLDBDebugSessionInfo &rSessionInfo(CMICmnLLDBDebugSessionInfo::Instance());
Hafiz Abid Qadeer0d51c152015-02-03 10:05:54 +00001039 lldb::SBProcess sbProcess = rSessionInfo.GetProcess();
1040 if (!sbProcess.IsValid())
Zachary Turner1d6af022014-11-17 18:06:21 +00001041 {
1042 SetError(CMIUtilString::Format(MIRSRC(IDS_CMD_ERR_INVALID_PROCESS), m_cmdData.strMiCmd.c_str()));
1043 return MIstatus::failure;
1044 }
Deepak Panickal877569c2014-06-24 16:35:50 +00001045
Zachary Turner1d6af022014-11-17 18:06:21 +00001046 const CMICmdArgValListBase::VecArgObjPtr_t &rVecRegNo(pArgRegNo->GetExpectedOptions());
Ilia Kb792be82015-02-06 12:43:05 +00001047 if (!rVecRegNo.empty())
Zachary Turner1d6af022014-11-17 18:06:21 +00001048 {
Ilia Kb792be82015-02-06 12:43:05 +00001049 // List of required registers
Hafiz Abid Qadeerec13f8252015-02-05 15:55:43 +00001050 CMICmdArgValListBase::VecArgObjPtr_t::const_iterator it = rVecRegNo.begin();
Ilia Kb792be82015-02-06 12:43:05 +00001051 while (it != rVecRegNo.end())
Hafiz Abid Qadeerec13f8252015-02-05 15:55:43 +00001052 {
1053 const CMICmdArgValNumber *pRegNo = static_cast<CMICmdArgValNumber *>(*it);
Ilia Kb792be82015-02-06 12:43:05 +00001054 const MIuint nRegIndex = pRegNo->GetValue();
1055 lldb::SBValue regValue = GetRegister(nRegIndex);
1056 if (regValue.IsValid())
1057 {
1058 const bool bOk = AddToOutput(nRegIndex, regValue, eFormat);
1059 if (!bOk)
1060 return MIstatus::failure;
1061 }
1062
Hafiz Abid Qadeerec13f8252015-02-05 15:55:43 +00001063 // Next
1064 ++it;
1065 }
1066 }
1067 else
1068 {
1069 // No register numbers are provided. Output all registers.
Ilia Kb792be82015-02-06 12:43:05 +00001070 lldb::SBThread thread = sbProcess.GetSelectedThread();
1071 lldb::SBFrame frame = thread.GetSelectedFrame();
1072 lldb::SBValueList registers = frame.GetRegisters();
1073 const MIuint nRegisters = registers.GetSize();
1074 MIuint nRegIndex = 0;
Hafiz Abid Qadeerec13f8252015-02-05 15:55:43 +00001075 for (MIuint i = 0; i < nRegisters; i++)
1076 {
Ilia Kb792be82015-02-06 12:43:05 +00001077 lldb::SBValue value = registers.GetValueAtIndex(i);
1078 const MIuint nRegChildren = value.GetNumChildren();
Hafiz Abid Qadeerec13f8252015-02-05 15:55:43 +00001079 for (MIuint j = 0; j < nRegChildren; j++)
1080 {
Ilia Kb792be82015-02-06 12:43:05 +00001081 lldb::SBValue regValue = value.GetChildAtIndex(j);
1082 if (regValue.IsValid())
Hafiz Abid Qadeerec13f8252015-02-05 15:55:43 +00001083 {
Ilia Kb792be82015-02-06 12:43:05 +00001084 const bool bOk = AddToOutput(nRegIndex, regValue, eFormat);
1085 if (!bOk)
1086 return MIstatus::failure;
Hafiz Abid Qadeerec13f8252015-02-05 15:55:43 +00001087 }
Ilia Kb792be82015-02-06 12:43:05 +00001088
1089 // Next
1090 ++nRegIndex;
Hafiz Abid Qadeerec13f8252015-02-05 15:55:43 +00001091 }
1092 }
Zachary Turner1d6af022014-11-17 18:06:21 +00001093 }
1094
1095 return MIstatus::success;
Deepak Panickal877569c2014-06-24 16:35:50 +00001096}
1097
1098//++ ------------------------------------------------------------------------------------
Zachary Turner1d6af022014-11-17 18:06:21 +00001099// Details: The invoker requires this function. The command prepares a MI Record Result
1100// for the work carried out in the Execute().
1101// Type: Overridden.
1102// Args: None.
1103// Return: MIstatus::success - Functional succeeded.
1104// MIstatus::failure - Functional failed.
1105// Throws: None.
Deepak Panickal877569c2014-06-24 16:35:50 +00001106//--
Zachary Turner1d6af022014-11-17 18:06:21 +00001107bool
1108CMICmdCmdDataListRegisterValues::Acknowledge(void)
Deepak Panickal877569c2014-06-24 16:35:50 +00001109{
Zachary Turner1d6af022014-11-17 18:06:21 +00001110 const CMICmnMIValueResult miValueResult("register-values", m_miValueList);
1111 const CMICmnMIResultRecord miRecordResult(m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Done, miValueResult);
1112 m_miResultRecord = miRecordResult;
1113
1114 return MIstatus::success;
Deepak Panickal877569c2014-06-24 16:35:50 +00001115}
1116
1117//++ ------------------------------------------------------------------------------------
Zachary Turner1d6af022014-11-17 18:06:21 +00001118// Details: Required by the CMICmdFactory when registering *this command. The factory
1119// calls this function to create an instance of *this command.
1120// Type: Static method.
1121// Args: None.
1122// Return: CMICmdBase * - Pointer to a new command.
1123// Throws: None.
Deepak Panickal877569c2014-06-24 16:35:50 +00001124//--
Zachary Turner1d6af022014-11-17 18:06:21 +00001125CMICmdBase *
1126CMICmdCmdDataListRegisterValues::CreateSelf(void)
Deepak Panickal877569c2014-06-24 16:35:50 +00001127{
Zachary Turner1d6af022014-11-17 18:06:21 +00001128 return new CMICmdCmdDataListRegisterValues();
Deepak Panickal877569c2014-06-24 16:35:50 +00001129}
1130
1131//++ ------------------------------------------------------------------------------------
Zachary Turner1d6af022014-11-17 18:06:21 +00001132// Details: Required by the CMICmdFactory when registering *this command. The factory
1133// calls this function to create an instance of *this command.
1134// Type: Method.
1135// Args: None.
1136// Return: lldb::SBValue - LLDB SBValue object.
1137// Throws: None.
Deepak Panickal877569c2014-06-24 16:35:50 +00001138//--
Zachary Turner1d6af022014-11-17 18:06:21 +00001139lldb::SBValue
1140CMICmdCmdDataListRegisterValues::GetRegister(const MIuint vRegisterIndex) const
Deepak Panickal877569c2014-06-24 16:35:50 +00001141{
Hafiz Abid Qadeer0d51c152015-02-03 10:05:54 +00001142 lldb::SBThread thread = CMICmnLLDBDebugSessionInfo::Instance().GetProcess().GetSelectedThread();
Zachary Turner1d6af022014-11-17 18:06:21 +00001143 lldb::SBFrame frame = thread.GetSelectedFrame();
1144 lldb::SBValueList registers = frame.GetRegisters();
1145 const MIuint nRegisters = registers.GetSize();
Ilia Kb792be82015-02-06 12:43:05 +00001146 MIuint nRegisterIndex(vRegisterIndex);
Zachary Turner1d6af022014-11-17 18:06:21 +00001147 for (MIuint i = 0; i < nRegisters; i++)
1148 {
1149 lldb::SBValue value = registers.GetValueAtIndex(i);
1150 const MIuint nRegChildren = value.GetNumChildren();
Ilia Kb792be82015-02-06 12:43:05 +00001151 if (nRegisterIndex >= nRegChildren)
Zachary Turner1d6af022014-11-17 18:06:21 +00001152 {
Ilia Kb792be82015-02-06 12:43:05 +00001153 nRegisterIndex -= nRegChildren;
1154 continue;
1155 }
1156
1157 lldb::SBValue value2 = value.GetChildAtIndex(nRegisterIndex);
1158 if (value2.IsValid())
1159 {
1160 return value2;
Zachary Turner1d6af022014-11-17 18:06:21 +00001161 }
1162 }
Deepak Panickal877569c2014-06-24 16:35:50 +00001163
Zachary Turner1d6af022014-11-17 18:06:21 +00001164 return lldb::SBValue();
Deepak Panickal877569c2014-06-24 16:35:50 +00001165}
1166
Hafiz Abid Qadeerec13f8252015-02-05 15:55:43 +00001167//++ ------------------------------------------------------------------------------------
1168// Details: Adds the register value to the output list.
1169// Type: Method.
1170// Args: Value of the register, its index and output format.
1171// Return: None
1172// Throws: None.
1173//--
Ilia Kb792be82015-02-06 12:43:05 +00001174bool
1175CMICmdCmdDataListRegisterValues::AddToOutput(const MIuint vnIndex, const lldb::SBValue &vrValue,
1176 CMICmnLLDBDebugSessionInfoVarObj::varFormat_e veVarFormat)
Hafiz Abid Qadeerec13f8252015-02-05 15:55:43 +00001177{
Ilia Kb792be82015-02-06 12:43:05 +00001178 const CMICmnMIValueConst miValueConst(CMIUtilString::Format("%u", vnIndex));
1179 const CMICmnMIValueResult miValueResult("number", miValueConst);
1180 CMICmnMIValueTuple miValueTuple(miValueResult);
1181 const CMIUtilString strRegValue(CMICmnLLDBDebugSessionInfoVarObj::GetValueStringFormatted(vrValue, veVarFormat));
1182 const CMICmnMIValueConst miValueConst2(strRegValue);
1183 const CMICmnMIValueResult miValueResult2("value", miValueConst2);
1184 bool bOk = miValueTuple.Add(miValueResult2);
1185 return bOk && m_miValueList.Add(miValueTuple);
Hafiz Abid Qadeerec13f8252015-02-05 15:55:43 +00001186}
1187
Deepak Panickal877569c2014-06-24 16:35:50 +00001188//---------------------------------------------------------------------------------------
1189//---------------------------------------------------------------------------------------
1190//---------------------------------------------------------------------------------------
1191
1192//++ ------------------------------------------------------------------------------------
Zachary Turner1d6af022014-11-17 18:06:21 +00001193// Details: CMICmdCmdDataListRegisterChanged constructor.
1194// Type: Method.
1195// Args: None.
1196// Return: None.
1197// Throws: None.
Deepak Panickal877569c2014-06-24 16:35:50 +00001198//--
Zachary Turner1d6af022014-11-17 18:06:21 +00001199CMICmdCmdDataListRegisterChanged::CMICmdCmdDataListRegisterChanged(void)
Deepak Panickal877569c2014-06-24 16:35:50 +00001200{
Zachary Turner1d6af022014-11-17 18:06:21 +00001201 // Command factory matches this name with that received from the stdin stream
1202 m_strMiCmd = "data-list-changed-registers";
1203
1204 // Required by the CMICmdFactory when registering *this command
1205 m_pSelfCreatorFn = &CMICmdCmdDataListRegisterChanged::CreateSelf;
Deepak Panickal877569c2014-06-24 16:35:50 +00001206}
1207
1208//++ ------------------------------------------------------------------------------------
Zachary Turner1d6af022014-11-17 18:06:21 +00001209// Details: CMICmdCmdDataListRegisterChanged destructor.
1210// Type: Overrideable.
1211// Args: None.
1212// Return: None.
1213// Throws: None.
Deepak Panickal877569c2014-06-24 16:35:50 +00001214//--
Zachary Turner1d6af022014-11-17 18:06:21 +00001215CMICmdCmdDataListRegisterChanged::~CMICmdCmdDataListRegisterChanged(void)
Deepak Panickal877569c2014-06-24 16:35:50 +00001216{
1217}
1218
1219//++ ------------------------------------------------------------------------------------
Zachary Turner1d6af022014-11-17 18:06:21 +00001220// Details: The invoker requires this function. The command does work in this function.
1221// The command is likely to communicate with the LLDB SBDebugger in here.
1222// Type: Overridden.
1223// Args: None.
1224// Return: MIstatus::success - Functional succeeded.
1225// MIstatus::failure - Functional failed.
1226// Throws: None.
Deepak Panickal877569c2014-06-24 16:35:50 +00001227//--
Zachary Turner1d6af022014-11-17 18:06:21 +00001228bool
1229CMICmdCmdDataListRegisterChanged::Execute(void)
Deepak Panickal877569c2014-06-24 16:35:50 +00001230{
Zachary Turner1d6af022014-11-17 18:06:21 +00001231 // Do nothing
1232
1233 return MIstatus::success;
Deepak Panickal877569c2014-06-24 16:35:50 +00001234}
1235
1236//++ ------------------------------------------------------------------------------------
Zachary Turner1d6af022014-11-17 18:06:21 +00001237// Details: The invoker requires this function. The command prepares a MI Record Result
1238// for the work carried out in the Execute().
1239// Type: Overridden.
1240// Args: None.
1241// Return: MIstatus::success - Functional succeeded.
1242// MIstatus::failure - Functional failed.
1243// Throws: None.
Deepak Panickal877569c2014-06-24 16:35:50 +00001244//--
Zachary Turner1d6af022014-11-17 18:06:21 +00001245bool
1246CMICmdCmdDataListRegisterChanged::Acknowledge(void)
Deepak Panickal877569c2014-06-24 16:35:50 +00001247{
Zachary Turner1d6af022014-11-17 18:06:21 +00001248 const CMICmnMIValueConst miValueConst(MIRSRC(IDS_WORD_NOT_IMPLEMENTED));
1249 const CMICmnMIValueResult miValueResult("msg", miValueConst);
1250 const CMICmnMIResultRecord miRecordResult(m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Error, miValueResult);
1251 m_miResultRecord = miRecordResult;
Deepak Panickal877569c2014-06-24 16:35:50 +00001252
Zachary Turner1d6af022014-11-17 18:06:21 +00001253 return MIstatus::success;
Deepak Panickal877569c2014-06-24 16:35:50 +00001254}
1255
1256//++ ------------------------------------------------------------------------------------
Zachary Turner1d6af022014-11-17 18:06:21 +00001257// Details: Required by the CMICmdFactory when registering *this command. The factory
1258// calls this function to create an instance of *this command.
1259// Type: Static method.
1260// Args: None.
1261// Return: CMICmdBase * - Pointer to a new command.
1262// Throws: None.
Deepak Panickal877569c2014-06-24 16:35:50 +00001263//--
Zachary Turner1d6af022014-11-17 18:06:21 +00001264CMICmdBase *
1265CMICmdCmdDataListRegisterChanged::CreateSelf(void)
Deepak Panickal877569c2014-06-24 16:35:50 +00001266{
Zachary Turner1d6af022014-11-17 18:06:21 +00001267 return new CMICmdCmdDataListRegisterChanged();
Deepak Panickal877569c2014-06-24 16:35:50 +00001268}
1269
1270//---------------------------------------------------------------------------------------
1271//---------------------------------------------------------------------------------------
1272//---------------------------------------------------------------------------------------
1273
1274//++ ------------------------------------------------------------------------------------
Zachary Turner1d6af022014-11-17 18:06:21 +00001275// Details: CMICmdCmdDataWriteMemoryBytes constructor.
1276// Type: Method.
1277// Args: None.
1278// Return: None.
1279// Throws: None.
Deepak Panickal877569c2014-06-24 16:35:50 +00001280//--
Zachary Turner1d6af022014-11-17 18:06:21 +00001281CMICmdCmdDataWriteMemoryBytes::CMICmdCmdDataWriteMemoryBytes(void)
1282 : m_constStrArgThread("thread")
1283 , m_constStrArgAddr("address")
1284 , m_constStrArgContents("contents")
1285 , m_constStrArgCount("count")
Deepak Panickal877569c2014-06-24 16:35:50 +00001286{
Zachary Turner1d6af022014-11-17 18:06:21 +00001287 // Command factory matches this name with that received from the stdin stream
1288 m_strMiCmd = "data-write-memory-bytes";
1289
1290 // Required by the CMICmdFactory when registering *this command
1291 m_pSelfCreatorFn = &CMICmdCmdDataWriteMemoryBytes::CreateSelf;
Deepak Panickal877569c2014-06-24 16:35:50 +00001292}
1293
1294//++ ------------------------------------------------------------------------------------
Zachary Turner1d6af022014-11-17 18:06:21 +00001295// Details: CMICmdCmdDataWriteMemoryBytes destructor.
1296// Type: Overrideable.
1297// Args: None.
1298// Return: None.
1299// Throws: None.
Deepak Panickal877569c2014-06-24 16:35:50 +00001300//--
Zachary Turner1d6af022014-11-17 18:06:21 +00001301CMICmdCmdDataWriteMemoryBytes::~CMICmdCmdDataWriteMemoryBytes(void)
Deepak Panickal877569c2014-06-24 16:35:50 +00001302{
1303}
1304
1305//++ ------------------------------------------------------------------------------------
Zachary Turner1d6af022014-11-17 18:06:21 +00001306// Details: The invoker requires this function. The parses the command line options
1307// arguments to extract values for each of those arguments.
1308// Type: Overridden.
1309// Args: None.
1310// Return: MIstatus::success - Functional succeeded.
1311// MIstatus::failure - Functional failed.
1312// Throws: None.
Deepak Panickal877569c2014-06-24 16:35:50 +00001313//--
Zachary Turner1d6af022014-11-17 18:06:21 +00001314bool
1315CMICmdCmdDataWriteMemoryBytes::ParseArgs(void)
Deepak Panickal877569c2014-06-24 16:35:50 +00001316{
Zachary Turner1d6af022014-11-17 18:06:21 +00001317 bool bOk =
1318 m_setCmdArgs.Add(*(new CMICmdArgValOptionLong(m_constStrArgThread, false, false, CMICmdArgValListBase::eArgValType_Number, 1)));
1319 bOk = bOk && m_setCmdArgs.Add(*(new CMICmdArgValString(m_constStrArgAddr, true, true, false, true)));
1320 bOk = bOk && m_setCmdArgs.Add(*(new CMICmdArgValString(m_constStrArgContents, true, true, true, true)));
1321 bOk = bOk && m_setCmdArgs.Add(*(new CMICmdArgValString(m_constStrArgCount, false, true, false, true)));
1322 return (bOk && ParseValidateCmdOptions());
Deepak Panickal877569c2014-06-24 16:35:50 +00001323}
1324
1325//++ ------------------------------------------------------------------------------------
Zachary Turner1d6af022014-11-17 18:06:21 +00001326// Details: The invoker requires this function. The command does work in this function.
1327// The command is likely to communicate with the LLDB SBDebugger in here.
1328// Type: Overridden.
1329// Args: None.
1330// Return: MIstatus::success - Functional succeeded.
1331// MIstatus::failure - Functional failed.
1332// Throws: None.
Deepak Panickal877569c2014-06-24 16:35:50 +00001333//--
Zachary Turner1d6af022014-11-17 18:06:21 +00001334bool
1335CMICmdCmdDataWriteMemoryBytes::Execute(void)
Deepak Panickal877569c2014-06-24 16:35:50 +00001336{
Zachary Turner1d6af022014-11-17 18:06:21 +00001337 // Do nothing - not reproduceable (yet) in Eclipse
1338 // CMICMDBASE_GETOPTION( pArgOffset, OptionShort, m_constStrArgOffset );
1339 // CMICMDBASE_GETOPTION( pArgAddr, String, m_constStrArgAddr );
1340 // CMICMDBASE_GETOPTION( pArgNumber, String, m_constStrArgNumber );
1341 // CMICMDBASE_GETOPTION( pArgContents, String, m_constStrArgContents );
1342 //
1343 // Numbers extracts as string types as they could be hex numbers
1344 // '&' is not recognised and so has to be removed
Deepak Panickal877569c2014-06-24 16:35:50 +00001345
Zachary Turner1d6af022014-11-17 18:06:21 +00001346 return MIstatus::success;
Deepak Panickal877569c2014-06-24 16:35:50 +00001347}
1348
1349//++ ------------------------------------------------------------------------------------
Zachary Turner1d6af022014-11-17 18:06:21 +00001350// Details: The invoker requires this function. The command prepares a MI Record Result
1351// for the work carried out in the Execute().
1352// Type: Overridden.
1353// Args: None.
1354// Return: MIstatus::success - Functional succeeded.
1355// MIstatus::failure - Functional failed.
1356// Throws: None.
Deepak Panickal877569c2014-06-24 16:35:50 +00001357//--
Zachary Turner1d6af022014-11-17 18:06:21 +00001358bool
1359CMICmdCmdDataWriteMemoryBytes::Acknowledge(void)
Deepak Panickal877569c2014-06-24 16:35:50 +00001360{
Zachary Turner1d6af022014-11-17 18:06:21 +00001361 const CMICmnMIValueConst miValueConst(MIRSRC(IDS_WORD_NOT_IMPLEMENTED));
1362 const CMICmnMIValueResult miValueResult("msg", miValueConst);
1363 const CMICmnMIResultRecord miRecordResult(m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Error, miValueResult);
1364 m_miResultRecord = miRecordResult;
Deepak Panickal877569c2014-06-24 16:35:50 +00001365
Zachary Turner1d6af022014-11-17 18:06:21 +00001366 return MIstatus::success;
Deepak Panickal877569c2014-06-24 16:35:50 +00001367}
1368
1369//++ ------------------------------------------------------------------------------------
Zachary Turner1d6af022014-11-17 18:06:21 +00001370// Details: Required by the CMICmdFactory when registering *this command. The factory
1371// calls this function to create an instance of *this command.
1372// Type: Static method.
1373// Args: None.
1374// Return: CMICmdBase * - Pointer to a new command.
1375// Throws: None.
Deepak Panickal877569c2014-06-24 16:35:50 +00001376//--
Zachary Turner1d6af022014-11-17 18:06:21 +00001377CMICmdBase *
1378CMICmdCmdDataWriteMemoryBytes::CreateSelf(void)
Deepak Panickal877569c2014-06-24 16:35:50 +00001379{
Zachary Turner1d6af022014-11-17 18:06:21 +00001380 return new CMICmdCmdDataWriteMemoryBytes();
Deepak Panickal877569c2014-06-24 16:35:50 +00001381}
1382
1383//---------------------------------------------------------------------------------------
1384//---------------------------------------------------------------------------------------
1385//---------------------------------------------------------------------------------------
1386
1387//++ ------------------------------------------------------------------------------------
Zachary Turner1d6af022014-11-17 18:06:21 +00001388// Details: CMICmdCmdDataWriteMemory constructor.
1389// Type: Method.
1390// Args: None.
1391// Return: None.
1392// Throws: None.
Deepak Panickal877569c2014-06-24 16:35:50 +00001393//--
Zachary Turner1d6af022014-11-17 18:06:21 +00001394CMICmdCmdDataWriteMemory::CMICmdCmdDataWriteMemory(void)
1395 : m_constStrArgThread("thread")
1396 , m_constStrArgOffset("o")
1397 , m_constStrArgAddr("address")
1398 , m_constStrArgD("d")
1399 , m_constStrArgNumber("a number")
1400 , m_constStrArgContents("contents")
1401 , m_nAddr(0)
1402 , m_nCount(0)
1403 , m_pBufferMemory(nullptr)
Deepak Panickal877569c2014-06-24 16:35:50 +00001404{
Zachary Turner1d6af022014-11-17 18:06:21 +00001405 // Command factory matches this name with that received from the stdin stream
1406 m_strMiCmd = "data-write-memory";
1407
1408 // Required by the CMICmdFactory when registering *this command
1409 m_pSelfCreatorFn = &CMICmdCmdDataWriteMemory::CreateSelf;
Deepak Panickal877569c2014-06-24 16:35:50 +00001410}
1411
1412//++ ------------------------------------------------------------------------------------
Zachary Turner1d6af022014-11-17 18:06:21 +00001413// Details: CMICmdCmdDataWriteMemory destructor.
1414// Type: Overrideable.
1415// Args: None.
1416// Return: None.
1417// Throws: None.
Deepak Panickal877569c2014-06-24 16:35:50 +00001418//--
Zachary Turner1d6af022014-11-17 18:06:21 +00001419CMICmdCmdDataWriteMemory::~CMICmdCmdDataWriteMemory(void)
Deepak Panickal877569c2014-06-24 16:35:50 +00001420{
Zachary Turner1d6af022014-11-17 18:06:21 +00001421 if (m_pBufferMemory != nullptr)
1422 {
1423 delete[] m_pBufferMemory;
1424 m_pBufferMemory = nullptr;
1425 }
Deepak Panickal877569c2014-06-24 16:35:50 +00001426}
1427
1428//++ ------------------------------------------------------------------------------------
Zachary Turner1d6af022014-11-17 18:06:21 +00001429// Details: The invoker requires this function. The parses the command line options
1430// arguments to extract values for each of those arguments.
1431// Type: Overridden.
1432// Args: None.
1433// Return: MIstatus::success - Functional succeeded.
1434// MIstatus::failure - Functional failed.
1435// Throws: None.
Deepak Panickal877569c2014-06-24 16:35:50 +00001436//--
Zachary Turner1d6af022014-11-17 18:06:21 +00001437bool
1438CMICmdCmdDataWriteMemory::ParseArgs(void)
Deepak Panickal877569c2014-06-24 16:35:50 +00001439{
Zachary Turner1d6af022014-11-17 18:06:21 +00001440 bool bOk =
1441 m_setCmdArgs.Add(*(new CMICmdArgValOptionLong(m_constStrArgThread, false, false, CMICmdArgValListBase::eArgValType_Number, 1)));
1442 bOk = bOk &&
1443 m_setCmdArgs.Add(*(new CMICmdArgValOptionShort(m_constStrArgOffset, false, true, CMICmdArgValListBase::eArgValType_Number, 1)));
1444 bOk = bOk && m_setCmdArgs.Add(*(new CMICmdArgValNumber(m_constStrArgAddr, true, true)));
1445 bOk = bOk && m_setCmdArgs.Add(*(new CMICmdArgValString(m_constStrArgD, true, true)));
1446 bOk = bOk && m_setCmdArgs.Add(*(new CMICmdArgValNumber(m_constStrArgNumber, true, true)));
1447 bOk = bOk && m_setCmdArgs.Add(*(new CMICmdArgValNumber(m_constStrArgContents, true, true)));
1448 return (bOk && ParseValidateCmdOptions());
Deepak Panickal877569c2014-06-24 16:35:50 +00001449}
1450
1451//++ ------------------------------------------------------------------------------------
Zachary Turner1d6af022014-11-17 18:06:21 +00001452// Details: The invoker requires this function. The command does work in this function.
1453// The command is likely to communicate with the LLDB SBDebugger in here.
1454// Type: Overridden.
1455// Args: None.
1456// Return: MIstatus::success - Functional succeeded.
1457// MIstatus::failure - Functional failed.
1458// Throws: None.
Deepak Panickal877569c2014-06-24 16:35:50 +00001459//--
Zachary Turner1d6af022014-11-17 18:06:21 +00001460bool
1461CMICmdCmdDataWriteMemory::Execute(void)
Deepak Panickal877569c2014-06-24 16:35:50 +00001462{
Zachary Turner1d6af022014-11-17 18:06:21 +00001463 CMICMDBASE_GETOPTION(pArgOffset, OptionShort, m_constStrArgOffset);
1464 CMICMDBASE_GETOPTION(pArgAddr, Number, m_constStrArgAddr);
1465 CMICMDBASE_GETOPTION(pArgNumber, Number, m_constStrArgNumber);
1466 CMICMDBASE_GETOPTION(pArgContents, Number, m_constStrArgContents);
Deepak Panickal877569c2014-06-24 16:35:50 +00001467
Zachary Turner1d6af022014-11-17 18:06:21 +00001468 MIuint nAddrOffset = 0;
1469 if (pArgOffset->GetFound() && !pArgOffset->GetExpectedOption<CMICmdArgValNumber, MIuint>(nAddrOffset))
1470 {
1471 SetError(CMIUtilString::Format(MIRSRC(IDS_CMD_ARGS_ERR_VALIDATION_INVALID), m_cmdData.strMiCmd.c_str(), m_constStrArgAddr.c_str()));
1472 return MIstatus::failure;
1473 }
1474 m_nAddr = pArgAddr->GetValue();
1475 m_nCount = pArgNumber->GetValue();
1476 const MIuint64 nValue = pArgContents->GetValue();
Deepak Panickal877569c2014-06-24 16:35:50 +00001477
Zachary Turner1d6af022014-11-17 18:06:21 +00001478 m_pBufferMemory = new MIuchar[m_nCount];
1479 if (m_pBufferMemory == nullptr)
1480 {
1481 SetError(CMIUtilString::Format(MIRSRC(IDS_CMD_ERR_MEMORY_ALLOC_FAILURE), m_cmdData.strMiCmd.c_str(), m_nCount));
1482 return MIstatus::failure;
1483 }
1484 *m_pBufferMemory = static_cast<MIchar>(nValue);
Deepak Panickal877569c2014-06-24 16:35:50 +00001485
Zachary Turner1d6af022014-11-17 18:06:21 +00001486 CMICmnLLDBDebugSessionInfo &rSessionInfo(CMICmnLLDBDebugSessionInfo::Instance());
Hafiz Abid Qadeer0d51c152015-02-03 10:05:54 +00001487 lldb::SBProcess sbProcess = rSessionInfo.GetProcess();
Zachary Turner1d6af022014-11-17 18:06:21 +00001488 lldb::SBError error;
1489 lldb::addr_t addr = static_cast<lldb::addr_t>(m_nAddr + nAddrOffset);
Hafiz Abid Qadeer0d51c152015-02-03 10:05:54 +00001490 const size_t nBytesWritten = sbProcess.WriteMemory(addr, (const void *)m_pBufferMemory, (size_t)m_nCount, error);
Zachary Turner1d6af022014-11-17 18:06:21 +00001491 if (nBytesWritten != static_cast<size_t>(m_nCount))
1492 {
1493 SetError(CMIUtilString::Format(MIRSRC(IDS_CMD_ERR_LLDB_ERR_NOT_WRITE_WHOLEBLK), m_cmdData.strMiCmd.c_str(), m_nCount, addr));
1494 return MIstatus::failure;
1495 }
1496 if (error.Fail())
1497 {
1498 lldb::SBStream err;
1499 const bool bOk = error.GetDescription(err);
1500 MIunused(bOk);
1501 SetError(
1502 CMIUtilString::Format(MIRSRC(IDS_CMD_ERR_LLDB_ERR_WRITE_MEM_BYTES), m_cmdData.strMiCmd.c_str(), m_nCount, addr, err.GetData()));
1503 return MIstatus::failure;
1504 }
1505
1506 return MIstatus::success;
Deepak Panickal877569c2014-06-24 16:35:50 +00001507}
1508
1509//++ ------------------------------------------------------------------------------------
Zachary Turner1d6af022014-11-17 18:06:21 +00001510// Details: The invoker requires this function. The command prepares a MI Record Result
1511// for the work carried out in the Execute().
1512// Type: Overridden.
1513// Args: None.
1514// Return: MIstatus::success - Functional succeeded.
1515// MIstatus::failure - Functional failed.
1516// Throws: None.
Deepak Panickal877569c2014-06-24 16:35:50 +00001517//--
Zachary Turner1d6af022014-11-17 18:06:21 +00001518bool
1519CMICmdCmdDataWriteMemory::Acknowledge(void)
Deepak Panickal877569c2014-06-24 16:35:50 +00001520{
Zachary Turner1d6af022014-11-17 18:06:21 +00001521 const CMICmnMIResultRecord miRecordResult(m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Done);
1522 m_miResultRecord = miRecordResult;
Deepak Panickal877569c2014-06-24 16:35:50 +00001523
Zachary Turner1d6af022014-11-17 18:06:21 +00001524 return MIstatus::success;
Deepak Panickal877569c2014-06-24 16:35:50 +00001525}
1526
1527//++ ------------------------------------------------------------------------------------
Zachary Turner1d6af022014-11-17 18:06:21 +00001528// Details: Required by the CMICmdFactory when registering *this command. The factory
1529// calls this function to create an instance of *this command.
1530// Type: Static method.
1531// Args: None.
1532// Return: CMICmdBase * - Pointer to a new command.
1533// Throws: None.
Deepak Panickal877569c2014-06-24 16:35:50 +00001534//--
Zachary Turner1d6af022014-11-17 18:06:21 +00001535CMICmdBase *
1536CMICmdCmdDataWriteMemory::CreateSelf(void)
Deepak Panickal877569c2014-06-24 16:35:50 +00001537{
Zachary Turner1d6af022014-11-17 18:06:21 +00001538 return new CMICmdCmdDataWriteMemory();
Deepak Panickal877569c2014-06-24 16:35:50 +00001539}