1 //===-- MICmdCmdGdbSet.cpp --------------------------------------*- C++ -*-===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 // Overview: CMICmdCmdGdbSet implementation.
13 #include "MICmdCmdGdbSet.h"
14 #include "MICmdArgValListOfN.h"
15 #include "MICmdArgValOptionLong.h"
16 #include "MICmdArgValString.h"
17 #include "MICmnLLDBDebugSessionInfo.h"
18 #include "MICmnMIResultRecord.h"
19 #include "MICmnMIValueConst.h"
22 const CMICmdCmdGdbSet::MapGdbOptionNameToFnGdbOptionPtr_t
23 CMICmdCmdGdbSet::ms_mapGdbOptionNameToFnGdbOptionPtr = {
24 {"target-async", &CMICmdCmdGdbSet::OptionFnTargetAsync},
25 {"print", &CMICmdCmdGdbSet::OptionFnPrint},
26 // { "auto-solib-add", &CMICmdCmdGdbSet::OptionFnAutoSolibAdd }, //
27 // Example code if need to implement GDB set other options
28 {"output-radix", &CMICmdCmdGdbSet::OptionFnOutputRadix},
29 {"solib-search-path", &CMICmdCmdGdbSet::OptionFnSolibSearchPath},
30 {"disassembly-flavor", &CMICmdCmdGdbSet::OptionFnDisassemblyFlavor},
31 {"fallback", &CMICmdCmdGdbSet::OptionFnFallback},
32 {"breakpoint", &CMICmdCmdGdbSet::OptionFnBreakpoint}};
35 //------------------------------------------------------------------------------------
36 // Details: CMICmdCmdGdbSet constructor.
42 CMICmdCmdGdbSet::CMICmdCmdGdbSet()
43 : m_constStrArgNamedGdbOption("option"), m_bGdbOptionRecognised(true),
44 m_bGdbOptionFnSuccessful(false), m_bGbbOptionFnHasError(false),
45 m_strGdbOptionFnError(MIRSRC(IDS_WORD_ERR_MSG_NOT_IMPLEMENTED_BRKTS)) {
46 // Command factory matches this name with that received from the stdin stream
47 m_strMiCmd = "gdb-set";
49 // Required by the CMICmdFactory when registering *this command
50 m_pSelfCreatorFn = &CMICmdCmdGdbSet::CreateSelf;
54 //------------------------------------------------------------------------------------
55 // Details: CMICmdCmdGdbSet destructor.
56 // Type: Overrideable.
61 CMICmdCmdGdbSet::~CMICmdCmdGdbSet() {}
64 //------------------------------------------------------------------------------------
65 // Details: The invoker requires this function. The parses the command line
67 // arguments to extract values for each of those arguments.
70 // Return: MIstatus::success - Functional succeeded.
71 // MIstatus::failure - Functional failed.
74 bool CMICmdCmdGdbSet::ParseArgs() {
75 m_setCmdArgs.Add(new CMICmdArgValListOfN(
76 m_constStrArgNamedGdbOption, true, true,
77 CMICmdArgValListBase::eArgValType_StringAnything));
78 return ParseValidateCmdOptions();
82 //------------------------------------------------------------------------------------
83 // Details: The invoker requires this function. The command is executed in this
85 // The command is likely to communicate with the LLDB SBDebugger in
89 // Return: MIstatus::success - Functional succeeded.
90 // MIstatus::failure - Functional failed.
93 bool CMICmdCmdGdbSet::Execute() {
94 CMICMDBASE_GETOPTION(pArgGdbOption, ListOfN, m_constStrArgNamedGdbOption);
95 const CMICmdArgValListBase::VecArgObjPtr_t &rVecWords(
96 pArgGdbOption->GetExpectedOptions());
98 // Get the gdb-set option to carry out. This option will be used as an action
99 // which should be done. Further arguments will be used as parameters for it.
100 CMICmdArgValListBase::VecArgObjPtr_t::const_iterator it = rVecWords.begin();
101 const CMICmdArgValString *pOption =
102 static_cast<const CMICmdArgValString *>(*it);
103 const CMIUtilString strOption(pOption->GetValue());
106 // Retrieve the parameter(s) for the option
107 CMIUtilString::VecString_t vecWords;
108 while (it != rVecWords.end()) {
109 const CMICmdArgValString *pWord =
110 static_cast<const CMICmdArgValString *>(*it);
111 vecWords.push_back(pWord->GetValue());
117 FnGdbOptionPtr pPrintRequestFn = nullptr;
118 if (!GetOptionFn(strOption, pPrintRequestFn)) {
119 // For unimplemented option handlers, fallback on a generic handler
120 // ToDo: Remove this when ALL options have been implemented
121 if (!GetOptionFn("fallback", pPrintRequestFn)) {
122 m_bGdbOptionRecognised = false;
123 m_strGdbOptionName = "fallback"; // This would be the strOption name
124 return MIstatus::success;
128 m_bGdbOptionFnSuccessful = (this->*(pPrintRequestFn))(vecWords);
129 if (!m_bGdbOptionFnSuccessful && !m_bGbbOptionFnHasError)
130 return MIstatus::failure;
132 return MIstatus::success;
136 //------------------------------------------------------------------------------------
137 // Details: The invoker requires this function. The command prepares a MI Record
139 // for the work carried out in the Execute() method.
142 // Return: MIstatus::success - Functional succeeded.
143 // MIstatus::failure - Functional failed.
146 bool CMICmdCmdGdbSet::Acknowledge() {
147 // Print error if option isn't recognized:
148 // ^error,msg="The request '%s' was not recognized, not implemented"
149 if (!m_bGdbOptionRecognised) {
150 const CMICmnMIValueConst miValueConst(
151 CMIUtilString::Format(MIRSRC(IDS_CMD_ERR_INFO_PRINTFN_NOT_FOUND),
152 m_strGdbOptionName.c_str()));
153 const CMICmnMIValueResult miValueResult("msg", miValueConst);
154 const CMICmnMIResultRecord miRecordResult(
155 m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Error,
157 m_miResultRecord = miRecordResult;
158 return MIstatus::success;
162 if (m_bGdbOptionFnSuccessful) {
163 const CMICmnMIResultRecord miRecordResult(
164 m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Done);
165 m_miResultRecord = miRecordResult;
166 return MIstatus::success;
169 // Print error if request failed:
170 // ^error,msg="The request '%s' failed.
171 const CMICmnMIValueConst miValueConst(CMIUtilString::Format(
172 MIRSRC(IDS_CMD_ERR_INFO_PRINTFN_FAILED), m_strGdbOptionFnError.c_str()));
173 const CMICmnMIValueResult miValueResult("msg", miValueConst);
174 const CMICmnMIResultRecord miRecordResult(
175 m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Error,
177 m_miResultRecord = miRecordResult;
179 return MIstatus::success;
183 //------------------------------------------------------------------------------------
184 // Details: Required by the CMICmdFactory when registering *this command. The
186 // calls this function to create an instance of *this command.
187 // Type: Static method.
189 // Return: CMICmdBase * - Pointer to a new command.
192 CMICmdBase *CMICmdCmdGdbSet::CreateSelf() { return new CMICmdCmdGdbSet(); }
195 //------------------------------------------------------------------------------------
196 // Details: Retrieve the print function's pointer for the matching print
199 // Args: vrPrintFnName - (R) The info requested.
200 // vrwpFn - (W) The print function's pointer of the function
202 // Return: bool - True = Print request is implemented, false = not found.
205 bool CMICmdCmdGdbSet::GetOptionFn(const CMIUtilString &vrPrintFnName,
206 FnGdbOptionPtr &vrwpFn) const {
209 const MapGdbOptionNameToFnGdbOptionPtr_t::const_iterator it =
210 ms_mapGdbOptionNameToFnGdbOptionPtr.find(vrPrintFnName);
211 if (it != ms_mapGdbOptionNameToFnGdbOptionPtr.end()) {
212 vrwpFn = (*it).second;
220 //------------------------------------------------------------------------------------
221 // Details: Carry out work to complete the GDB set option 'target-async' to
223 // and send back information asked for.
225 // Args: vrWords - (R) List of additional parameters used by this option.
226 // Return: MIstatus::success - Function succeeded.
227 // MIstatus::failure - Function failed.
230 bool CMICmdCmdGdbSet::OptionFnTargetAsync(
231 const CMIUtilString::VecString_t &vrWords) {
232 bool bAsyncMode = false;
235 if (vrWords.size() > 1)
236 // Too many arguments.
238 else if (vrWords.size() == 0)
239 // If no arguments, default is "on".
241 else if (CMIUtilString::Compare(vrWords[0], "on"))
243 else if (CMIUtilString::Compare(vrWords[0], "off"))
246 // Unrecognized argument.
251 m_bGbbOptionFnHasError = true;
252 m_strGdbOptionFnError = MIRSRC(IDS_CMD_ERR_GDBSET_OPT_TARGETASYNC);
253 return MIstatus::failure;
256 // Turn async mode on/off.
257 CMICmnLLDBDebugSessionInfo &rSessionInfo(
258 CMICmnLLDBDebugSessionInfo::Instance());
259 rSessionInfo.GetDebugger().SetAsync(bAsyncMode);
261 return MIstatus::success;
265 //------------------------------------------------------------------------------------
266 // Details: Carry out work to complete the GDB set option
267 // 'print-char-array-as-string' to
268 // prepare and send back information asked for.
270 // Args: vrWords - (R) List of additional parameters used by this option.
271 // Return: MIstatus::success - Function succeeded.
272 // MIstatus::failure - Function failed.
275 bool CMICmdCmdGdbSet::OptionFnPrint(const CMIUtilString::VecString_t &vrWords) {
276 const bool bAllArgs(vrWords.size() == 2);
277 const bool bArgOn(bAllArgs && (CMIUtilString::Compare(vrWords[1], "on") ||
278 CMIUtilString::Compare(vrWords[1], "1")));
279 const bool bArgOff(bAllArgs && (CMIUtilString::Compare(vrWords[1], "off") ||
280 CMIUtilString::Compare(vrWords[1], "0")));
281 if (!bAllArgs || (!bArgOn && !bArgOff)) {
282 m_bGbbOptionFnHasError = true;
283 m_strGdbOptionFnError = MIRSRC(IDS_CMD_ERR_GDBSET_OPT_PRINT_BAD_ARGS);
284 return MIstatus::failure;
287 const CMIUtilString strOption(vrWords[0]);
288 CMIUtilString strOptionKey;
289 if (CMIUtilString::Compare(strOption, "char-array-as-string"))
290 strOptionKey = m_rLLDBDebugSessionInfo.m_constStrPrintCharArrayAsString;
291 else if (CMIUtilString::Compare(strOption, "expand-aggregates"))
292 strOptionKey = m_rLLDBDebugSessionInfo.m_constStrPrintExpandAggregates;
293 else if (CMIUtilString::Compare(strOption, "aggregate-field-names"))
294 strOptionKey = m_rLLDBDebugSessionInfo.m_constStrPrintAggregateFieldNames;
296 m_bGbbOptionFnHasError = true;
297 m_strGdbOptionFnError = CMIUtilString::Format(
298 MIRSRC(IDS_CMD_ERR_GDBSET_OPT_PRINT_UNKNOWN_OPTION), strOption.c_str());
299 return MIstatus::failure;
302 const bool bOptionValue(bArgOn);
303 if (!m_rLLDBDebugSessionInfo.SharedDataAdd<bool>(strOptionKey,
305 m_bGbbOptionFnHasError = false;
306 SetError(CMIUtilString::Format(MIRSRC(IDS_DBGSESSION_ERR_SHARED_DATA_ADD),
307 m_cmdData.strMiCmd.c_str(),
308 strOptionKey.c_str()));
309 return MIstatus::failure;
312 return MIstatus::success;
316 //------------------------------------------------------------------------------------
317 // Details: Carry out work to complete the GDB set option 'solib-search-path' to
319 // and send back information asked for.
321 // Args: vrWords - (R) List of additional parameters used by this option.
322 // Return: MIstatus::success - Functional succeeded.
323 // MIstatus::failure - Functional failed.
326 bool CMICmdCmdGdbSet::OptionFnSolibSearchPath(
327 const CMIUtilString::VecString_t &vrWords) {
328 // Check we have at least one argument
329 if (vrWords.size() < 1) {
330 m_bGbbOptionFnHasError = true;
331 m_strGdbOptionFnError = MIRSRC(IDS_CMD_ERR_GDBSET_OPT_SOLIBSEARCHPATH);
332 return MIstatus::failure;
334 const CMIUtilString &rStrValSolibPath(vrWords[0]);
336 // Add 'solib-search-path' to the shared data list
337 const CMIUtilString &rStrKeySolibPath(
338 m_rLLDBDebugSessionInfo.m_constStrSharedDataSolibPath);
339 if (!m_rLLDBDebugSessionInfo.SharedDataAdd<CMIUtilString>(rStrKeySolibPath,
341 m_bGbbOptionFnHasError = false;
342 SetError(CMIUtilString::Format(MIRSRC(IDS_DBGSESSION_ERR_SHARED_DATA_ADD),
343 m_cmdData.strMiCmd.c_str(),
344 rStrKeySolibPath.c_str()));
345 return MIstatus::failure;
348 return MIstatus::success;
352 //------------------------------------------------------------------------------------
353 // Details: Carry out work to complete the GDB set option 'output-radix' to
355 // and send back information asked for.
357 // Args: vrWords - (R) List of additional parameters used by this option.
358 // Return: MIstatus::success - Functional succeeded.
359 // MIstatus::failure - Functional failed.
362 bool CMICmdCmdGdbSet::OptionFnOutputRadix(
363 const CMIUtilString::VecString_t &vrWords) {
364 // Check we have at least one argument
365 if (vrWords.size() < 1) {
366 m_bGbbOptionFnHasError = true;
367 m_strGdbOptionFnError = MIRSRC(IDS_CMD_ERR_GDBSET_OPT_SOLIBSEARCHPATH);
368 return MIstatus::failure;
370 const CMIUtilString &rStrValOutputRadix(vrWords[0]);
372 CMICmnLLDBDebugSessionInfoVarObj::varFormat_e format =
373 CMICmnLLDBDebugSessionInfoVarObj::eVarFormat_Invalid;
375 if (rStrValOutputRadix.ExtractNumber(radix)) {
378 format = CMICmnLLDBDebugSessionInfoVarObj::eVarFormat_Octal;
381 format = CMICmnLLDBDebugSessionInfoVarObj::eVarFormat_Natural;
384 format = CMICmnLLDBDebugSessionInfoVarObj::eVarFormat_Hex;
387 format = CMICmnLLDBDebugSessionInfoVarObj::eVarFormat_Invalid;
391 if (format == CMICmnLLDBDebugSessionInfoVarObj::eVarFormat_Invalid) {
392 m_bGbbOptionFnHasError = false;
393 SetError(CMIUtilString::Format(MIRSRC(IDS_DBGSESSION_ERR_SHARED_DATA_ADD),
394 m_cmdData.strMiCmd.c_str(), "Output Radix"));
395 return MIstatus::failure;
397 CMICmnLLDBDebugSessionInfoVarObj::VarObjSetFormat(format);
399 return MIstatus::success;
403 //------------------------------------------------------------------------------------
404 // Details: Carry out work to complete the GDB set option 'disassembly-flavor'
406 // and send back information asked for.
408 // Args: vrWords - (R) List of additional parameters used by this option.
409 // Return: MIstatus::success - Functional succeeded.
410 // MIstatus::failure - Functional failed.
413 bool CMICmdCmdGdbSet::OptionFnDisassemblyFlavor(
414 const CMIUtilString::VecString_t &vrWords) {
415 // Check we have at least one argument
416 if (vrWords.size() < 1) {
417 m_bGbbOptionFnHasError = true;
418 // m_strGdbOptionFnError = MIRSRC(IDS_CMD_ERR_GDBSET_OPT_SOLIBSEARCHPATH);
419 return MIstatus::failure;
421 const CMIUtilString &rStrValDisasmFlavor(vrWords[0]);
423 lldb::SBDebugger &rDbgr = m_rLLDBDebugSessionInfo.GetDebugger();
424 lldb::SBError error = lldb::SBDebugger::SetInternalVariable(
425 "target.x86-disassembly-flavor", rStrValDisasmFlavor.c_str(),
426 rDbgr.GetInstanceName());
428 m_strGdbOptionFnError = error.GetCString();
429 return MIstatus::failure;
432 return MIstatus::success;
436 //------------------------------------------------------------------------------------
437 // Details: Carry out work to complete the GDB set option 'breakpoint' to
439 // and send back information asked for.
441 // Args: vrWords - (R) List of additional parameters used by this option.
442 // Return: MIstatus::success - Function succeeded.
443 // MIstatus::failure - Function failed.
446 bool CMICmdCmdGdbSet::OptionFnBreakpoint(
447 const CMIUtilString::VecString_t &vrWords) {
448 bool bPending = false;
451 if (vrWords.size() != 2)
452 // Wrong number of arguments.
454 else if (CMIUtilString::Compare(vrWords[0], "pending") &&
455 (CMIUtilString::Compare(vrWords[1], "on") ||
456 CMIUtilString::Compare(vrWords[1], "1")))
458 else if (CMIUtilString::Compare(vrWords[0], "pending") &&
459 (CMIUtilString::Compare(vrWords[1], "off") ||
460 CMIUtilString::Compare(vrWords[1], "0")))
463 // Unrecognized argument(s).
468 m_bGbbOptionFnHasError = false;
469 SetError(MIRSRC(IDS_CMD_ERR_GDBSET_OPT_BREAKPOINT));
470 return MIstatus::failure;
473 CMIUtilString sPendingVal = bPending ? "on" : "off";
474 CMIUtilString sKey = "breakpoint.pending";
475 if (!m_rLLDBDebugSessionInfo.SharedDataAdd(sKey, sPendingVal)) {
476 m_bGbbOptionFnHasError = false;
477 SetError(CMIUtilString::Format(MIRSRC(IDS_DBGSESSION_ERR_SHARED_DATA_ADD),
478 m_cmdData.strMiCmd.c_str(), sKey.c_str()));
479 return MIstatus::failure;
482 return MIstatus::success;
486 //------------------------------------------------------------------------------------
487 // Details: Carry out work to complete the GDB set option to prepare and send
489 // requested information.
492 // Return: MIstatus::success - Functional succeeded.
493 // MIstatus::failure - Functional failed.
496 bool CMICmdCmdGdbSet::OptionFnFallback(
497 const CMIUtilString::VecString_t &vrWords) {
500 // Do nothing - intentional. This is a fallback function to do nothing.
501 // This allows the search for gdb-set options to always succeed when the
503 // found (implemented).
505 return MIstatus::success;