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