1//===-- MICmdCmdGdbSet.cpp --------------------------------------*- C++ -*-===// 2// 3// The LLVM Compiler Infrastructure 4// 5// This file is distributed under the University of Illinois Open Source 6// License. See LICENSE.TXT for details. 7// 8//===----------------------------------------------------------------------===// 9 10// Overview: CMICmdCmdGdbSet implementation. 11 12// In-house headers: 13#include "MICmdCmdGdbSet.h" 14#include "MICmnMIResultRecord.h" 15#include "MICmnMIValueConst.h" 16#include "MICmdArgValString.h" 17#include "MICmdArgValListOfN.h" 18#include "MICmdArgValOptionLong.h" 19#include "MICmnLLDBDebugSessionInfo.h" 20 21// Instantiations: 22const CMICmdCmdGdbSet::MapGdbOptionNameToFnGdbOptionPtr_t CMICmdCmdGdbSet::ms_mapGdbOptionNameToFnGdbOptionPtr = { 23 {"target-async", &CMICmdCmdGdbSet::OptionFnTargetAsync}, 24 {"print", &CMICmdCmdGdbSet::OptionFnPrint}, 25 // { "auto-solib-add", &CMICmdCmdGdbSet::OptionFnAutoSolibAdd }, // Example code if need to implement GDB set other options 26 {"output-radix", &CMICmdCmdGdbSet::OptionFnOutputRadix}, 27 {"solib-search-path", &CMICmdCmdGdbSet::OptionFnSolibSearchPath}, 28 {"fallback", &CMICmdCmdGdbSet::OptionFnFallback}}; 29 30//++ ------------------------------------------------------------------------------------ 31// Details: CMICmdCmdGdbSet constructor. 32// Type: Method. 33// Args: None. 34// Return: None. 35// Throws: None. 36//-- 37CMICmdCmdGdbSet::CMICmdCmdGdbSet() 38 : m_constStrArgNamedGdbOption("option") 39 , m_bGdbOptionRecognised(true) 40 , m_bGdbOptionFnSuccessful(false) 41 , m_bGbbOptionFnHasError(false) 42 , m_strGdbOptionFnError(MIRSRC(IDS_WORD_ERR_MSG_NOT_IMPLEMENTED_BRKTS)) 43{ 44 // Command factory matches this name with that received from the stdin stream 45 m_strMiCmd = "gdb-set"; 46 47 // Required by the CMICmdFactory when registering *this command 48 m_pSelfCreatorFn = &CMICmdCmdGdbSet::CreateSelf; 49} 50 51//++ ------------------------------------------------------------------------------------ 52// Details: CMICmdCmdGdbSet destructor. 53// Type: Overrideable. 54// Args: None. 55// Return: None. 56// Throws: None. 57//-- 58CMICmdCmdGdbSet::~CMICmdCmdGdbSet() 59{ 60} 61 62//++ ------------------------------------------------------------------------------------ 63// Details: The invoker requires this function. The parses the command line options 64// arguments to extract values for each of those arguments. 65// Type: Overridden. 66// Args: None. 67// Return: MIstatus::success - Functional succeeded. 68// MIstatus::failure - Functional failed. 69// Throws: None. 70//-- 71bool 72CMICmdCmdGdbSet::ParseArgs() 73{ 74 m_setCmdArgs.Add( 75 new CMICmdArgValListOfN(m_constStrArgNamedGdbOption, true, true, CMICmdArgValListBase::eArgValType_StringAnything)); 76 return ParseValidateCmdOptions(); 77} 78 79//++ ------------------------------------------------------------------------------------ 80// Details: The invoker requires this function. The command is executed in this function. 81// The command is likely to communicate with the LLDB SBDebugger in here. 82// Type: Overridden. 83// Args: None. 84// Return: MIstatus::success - Functional succeeded. 85// MIstatus::failure - Functional failed. 86// Throws: None. 87//-- 88bool 89CMICmdCmdGdbSet::Execute() 90{ 91 CMICMDBASE_GETOPTION(pArgGdbOption, ListOfN, m_constStrArgNamedGdbOption); 92 const CMICmdArgValListBase::VecArgObjPtr_t &rVecWords(pArgGdbOption->GetExpectedOptions()); 93 94 // Get the gdb-set option to carry out. This option will be used as an action 95 // which should be done. Further arguments will be used as parameters for it. 96 CMICmdArgValListBase::VecArgObjPtr_t::const_iterator it = rVecWords.begin(); 97 const CMICmdArgValString *pOption = static_cast<const CMICmdArgValString *>(*it); 98 const CMIUtilString strOption(pOption->GetValue()); 99 ++it; 100 101 // Retrieve the parameter(s) for the option 102 CMIUtilString::VecString_t vecWords; 103 while (it != rVecWords.end()) 104 { 105 const CMICmdArgValString *pWord = static_cast<const CMICmdArgValString *>(*it); 106 vecWords.push_back(pWord->GetValue()); 107 108 // Next 109 ++it; 110 } 111 112 FnGdbOptionPtr pPrintRequestFn = nullptr; 113 if (!GetOptionFn(strOption, pPrintRequestFn)) 114 { 115 // For unimplemented option handlers, fallback on a generic handler 116 // ToDo: Remove this when ALL options have been implemented 117 if (!GetOptionFn("fallback", pPrintRequestFn)) 118 { 119 m_bGdbOptionRecognised = false; 120 m_strGdbOptionName = "fallback"; // This would be the strOption name 121 return MIstatus::success; 122 } 123 } 124 125 m_bGdbOptionFnSuccessful = (this->*(pPrintRequestFn))(vecWords); 126 if (!m_bGdbOptionFnSuccessful && !m_bGbbOptionFnHasError) 127 return MIstatus::failure; 128 129 return MIstatus::success; 130} 131 132//++ ------------------------------------------------------------------------------------ 133// Details: The invoker requires this function. The command prepares a MI Record Result 134// for the work carried out in the Execute() method. 135// Type: Overridden. 136// Args: None. 137// Return: MIstatus::success - Functional succeeded. 138// MIstatus::failure - Functional failed. 139// Throws: None. 140//-- 141bool 142CMICmdCmdGdbSet::Acknowledge() 143{ 144 // Print error if option isn't recognized: 145 // ^error,msg="The request '%s' was not recognized, not implemented" 146 if (!m_bGdbOptionRecognised) 147 { 148 const CMICmnMIValueConst miValueConst( 149 CMIUtilString::Format(MIRSRC(IDS_CMD_ERR_INFO_PRINTFN_NOT_FOUND), m_strGdbOptionName.c_str())); 150 const CMICmnMIValueResult miValueResult("msg", miValueConst); 151 const CMICmnMIResultRecord miRecordResult(m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Error, miValueResult); 152 m_miResultRecord = miRecordResult; 153 return MIstatus::success; 154 } 155 156 // ^done,value="%s" 157 if (m_bGdbOptionFnSuccessful) 158 { 159 const CMICmnMIResultRecord miRecordResult(m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Done); 160 m_miResultRecord = miRecordResult; 161 return MIstatus::success; 162 } 163 164 // Print error if request failed: 165 // ^error,msg="The request '%s' failed. 166 const CMICmnMIValueConst miValueConst(CMIUtilString::Format(MIRSRC(IDS_CMD_ERR_INFO_PRINTFN_FAILED), m_strGdbOptionFnError.c_str())); 167 const CMICmnMIValueResult miValueResult("msg", miValueConst); 168 const CMICmnMIResultRecord miRecordResult(m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Error, miValueResult); 169 m_miResultRecord = miRecordResult; 170 171 return MIstatus::success; 172} 173 174//++ ------------------------------------------------------------------------------------ 175// Details: Required by the CMICmdFactory when registering *this command. The factory 176// calls this function to create an instance of *this command. 177// Type: Static method. 178// Args: None. 179// Return: CMICmdBase * - Pointer to a new command. 180// Throws: None. 181//-- 182CMICmdBase * 183CMICmdCmdGdbSet::CreateSelf() 184{ 185 return new CMICmdCmdGdbSet(); 186} 187 188//++ ------------------------------------------------------------------------------------ 189// Details: Retrieve the print function's pointer for the matching print request. 190// Type: Method. 191// Args: vrPrintFnName - (R) The info requested. 192// vrwpFn - (W) The print function's pointer of the function to carry out 193// Return: bool - True = Print request is implemented, false = not found. 194// Throws: None. 195//-- 196bool 197CMICmdCmdGdbSet::GetOptionFn(const CMIUtilString &vrPrintFnName, FnGdbOptionPtr &vrwpFn) const 198{ 199 vrwpFn = nullptr; 200 201 const MapGdbOptionNameToFnGdbOptionPtr_t::const_iterator it = ms_mapGdbOptionNameToFnGdbOptionPtr.find(vrPrintFnName); 202 if (it != ms_mapGdbOptionNameToFnGdbOptionPtr.end()) 203 { 204 vrwpFn = (*it).second; 205 return true; 206 } 207 208 return false; 209} 210 211//++ ------------------------------------------------------------------------------------ 212// Details: Carry out work to complete the GDB set option 'target-async' to prepare 213// and send back information asked for. 214// Type: Method. 215// Args: vrWords - (R) List of additional parameters used by this option. 216// Return: MIstatus::success - Function succeeded. 217// MIstatus::failure - Function failed. 218// Throws: None. 219//-- 220bool 221CMICmdCmdGdbSet::OptionFnTargetAsync(const CMIUtilString::VecString_t &vrWords) 222{ 223 bool bAsyncMode = false; 224 bool bOk = true; 225 226 if (vrWords.size() > 1) 227 // Too many arguments. 228 bOk = false; 229 else if (vrWords.size() == 0) 230 // If no arguments, default is "on". 231 bAsyncMode = true; 232 else if (CMIUtilString::Compare(vrWords[0], "on")) 233 bAsyncMode = true; 234 else if (CMIUtilString::Compare(vrWords[0], "off")) 235 bAsyncMode = false; 236 else 237 // Unrecognized argument. 238 bOk = false; 239 240 if (!bOk) 241 { 242 // Report error. 243 m_bGbbOptionFnHasError = true; 244 m_strGdbOptionFnError = MIRSRC(IDS_CMD_ERR_GDBSET_OPT_TARGETASYNC); 245 return MIstatus::failure; 246 } 247 248 // Turn async mode on/off. 249 CMICmnLLDBDebugSessionInfo &rSessionInfo(CMICmnLLDBDebugSessionInfo::Instance()); 250 rSessionInfo.GetDebugger().SetAsync(bAsyncMode); 251 252 return MIstatus::success; 253} 254 255//++ ------------------------------------------------------------------------------------ 256// Details: Carry out work to complete the GDB set option 'print-char-array-as-string' to 257// prepare and send back information asked for. 258// Type: Method. 259// Args: vrWords - (R) List of additional parameters used by this option. 260// Return: MIstatus::success - Function succeeded. 261// MIstatus::failure - Function failed. 262// Throws: None. 263//-- 264bool 265CMICmdCmdGdbSet::OptionFnPrint(const CMIUtilString::VecString_t &vrWords) 266{ 267 const bool bAllArgs(vrWords.size() == 2); 268 const bool bArgOn(bAllArgs && (CMIUtilString::Compare(vrWords[1], "on") || CMIUtilString::Compare(vrWords[1], "1"))); 269 const bool bArgOff(bAllArgs && (CMIUtilString::Compare(vrWords[1], "off") || CMIUtilString::Compare(vrWords[1], "0"))); 270 if (!bAllArgs || (!bArgOn && !bArgOff)) 271 { 272 m_bGbbOptionFnHasError = true; 273 m_strGdbOptionFnError = MIRSRC(IDS_CMD_ERR_GDBSET_OPT_PRINT_BAD_ARGS); 274 return MIstatus::failure; 275 } 276 277 const CMIUtilString strOption(vrWords[0]); 278 CMIUtilString strOptionKey; 279 if (CMIUtilString::Compare(strOption, "char-array-as-string")) 280 strOptionKey = m_rLLDBDebugSessionInfo.m_constStrPrintCharArrayAsString; 281 else if (CMIUtilString::Compare(strOption, "expand-aggregates")) 282 strOptionKey = m_rLLDBDebugSessionInfo.m_constStrPrintExpandAggregates; 283 else if (CMIUtilString::Compare(strOption, "aggregate-field-names")) 284 strOptionKey = m_rLLDBDebugSessionInfo.m_constStrPrintAggregateFieldNames; 285 else 286 { 287 m_bGbbOptionFnHasError = true; 288 m_strGdbOptionFnError = CMIUtilString::Format(MIRSRC(IDS_CMD_ERR_GDBSET_OPT_PRINT_UNKNOWN_OPTION), strOption.c_str()); 289 return MIstatus::failure; 290 } 291 292 const bool bOptionValue(bArgOn); 293 if (!m_rLLDBDebugSessionInfo.SharedDataAdd<bool>(strOptionKey, bOptionValue)) 294 { 295 m_bGbbOptionFnHasError = false; 296 SetError(CMIUtilString::Format(MIRSRC(IDS_DBGSESSION_ERR_SHARED_DATA_ADD), m_cmdData.strMiCmd.c_str(), strOptionKey.c_str())); 297 return MIstatus::failure; 298 } 299 300 return MIstatus::success; 301} 302 303//++ ------------------------------------------------------------------------------------ 304// Details: Carry out work to complete the GDB set option 'solib-search-path' to prepare 305// and send back information asked for. 306// Type: Method. 307// Args: vrWords - (R) List of additional parameters used by this option. 308// Return: MIstatus::success - Functional succeeded. 309// MIstatus::failure - Functional failed. 310// Throws: None. 311//-- 312bool 313CMICmdCmdGdbSet::OptionFnSolibSearchPath(const CMIUtilString::VecString_t &vrWords) 314{ 315 // Check we have at least one argument 316 if (vrWords.size() < 1) 317 { 318 m_bGbbOptionFnHasError = true; 319 m_strGdbOptionFnError = MIRSRC(IDS_CMD_ERR_GDBSET_OPT_SOLIBSEARCHPATH); 320 return MIstatus::failure; 321 } 322 const CMIUtilString &rStrValSolibPath(vrWords[0]); 323 324 // Add 'solib-search-path' to the shared data list 325 const CMIUtilString &rStrKeySolibPath(m_rLLDBDebugSessionInfo.m_constStrSharedDataSolibPath); 326 if (!m_rLLDBDebugSessionInfo.SharedDataAdd<CMIUtilString>(rStrKeySolibPath, rStrValSolibPath)) 327 { 328 m_bGbbOptionFnHasError = false; 329 SetError(CMIUtilString::Format(MIRSRC(IDS_DBGSESSION_ERR_SHARED_DATA_ADD), m_cmdData.strMiCmd.c_str(), rStrKeySolibPath.c_str())); 330 return MIstatus::failure; 331 } 332 333 return MIstatus::success; 334} 335 336//++ ------------------------------------------------------------------------------------ 337// Details: Carry out work to complete the GDB set option 'output-radix' to prepare 338// and send back information asked for. 339// Type: Method. 340// Args: vrWords - (R) List of additional parameters used by this option. 341// Return: MIstatus::success - Functional succeeded. 342// MIstatus::failure - Functional failed. 343// Throws: None. 344//-- 345bool 346CMICmdCmdGdbSet::OptionFnOutputRadix(const CMIUtilString::VecString_t &vrWords) 347{ 348 // Check we have at least one argument 349 if (vrWords.size() < 1) 350 { 351 m_bGbbOptionFnHasError = true; 352 m_strGdbOptionFnError = MIRSRC(IDS_CMD_ERR_GDBSET_OPT_SOLIBSEARCHPATH); 353 return MIstatus::failure; 354 } 355 const CMIUtilString &rStrValOutputRadix(vrWords[0]); 356 357 CMICmnLLDBDebugSessionInfoVarObj::varFormat_e format = CMICmnLLDBDebugSessionInfoVarObj::eVarFormat_Invalid; 358 MIint64 radix; 359 if (rStrValOutputRadix.ExtractNumber(radix)) 360 { 361 switch (radix) 362 { 363 case 8: 364 format = CMICmnLLDBDebugSessionInfoVarObj::eVarFormat_Octal; 365 break; 366 case 10: 367 format = CMICmnLLDBDebugSessionInfoVarObj::eVarFormat_Natural; 368 break; 369 case 16: 370 format = CMICmnLLDBDebugSessionInfoVarObj::eVarFormat_Hex; 371 break; 372 default: 373 format = CMICmnLLDBDebugSessionInfoVarObj::eVarFormat_Invalid; 374 break; 375 } 376 } 377 if (format == CMICmnLLDBDebugSessionInfoVarObj::eVarFormat_Invalid) 378 { 379 m_bGbbOptionFnHasError = false; 380 SetError(CMIUtilString::Format(MIRSRC(IDS_DBGSESSION_ERR_SHARED_DATA_ADD), m_cmdData.strMiCmd.c_str(), "Output Radix")); 381 return MIstatus::failure; 382 } 383 CMICmnLLDBDebugSessionInfoVarObj::VarObjSetFormat(format); 384 385 return MIstatus::success; 386} 387 388//++ ------------------------------------------------------------------------------------ 389// Details: Carry out work to complete the GDB set option to prepare and send back the 390// requested information. 391// Type: Method. 392// Args: None. 393// Return: MIstatus::success - Functional succeeded. 394// MIstatus::failure - Functional failed. 395// Throws: None. 396//-- 397bool 398CMICmdCmdGdbSet::OptionFnFallback(const CMIUtilString::VecString_t &vrWords) 399{ 400 MIunused(vrWords); 401 402 // Do nothing - intentional. This is a fallback function to do nothing. 403 // This allows the search for gdb-set options to always succeed when the option is not 404 // found (implemented). 405 406 return MIstatus::success; 407} 408