]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/llvm-project/lldb/tools/lldb-mi/MICmdCmdGdbShow.cpp
MFC r355940:
[FreeBSD/FreeBSD.git] / contrib / llvm-project / lldb / tools / lldb-mi / MICmdCmdGdbShow.cpp
1 //===-- MICmdCmdGdbShow.cpp -------------------------------------*- C++ -*-===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8
9 // Overview:    CMICmdCmdGdbShow implementation.
10
11 // Third party headers:
12 #include "lldb/API/SBCompileUnit.h"
13 #include "lldb/API/SBFrame.h"
14 #include "lldb/API/SBLanguageRuntime.h"
15 #include "lldb/API/SBStringList.h"
16 #include "lldb/API/SBThread.h"
17
18 // In-house headers:
19 #include "MICmdArgValListOfN.h"
20 #include "MICmdArgValOptionLong.h"
21 #include "MICmdArgValString.h"
22 #include "MICmdCmdGdbShow.h"
23 #include "MICmnLLDBDebugSessionInfo.h"
24 #include "MICmnMIResultRecord.h"
25 #include "MICmnMIValueConst.h"
26
27 // Instantiations:
28 const CMICmdCmdGdbShow::MapGdbOptionNameToFnGdbOptionPtr_t
29     CMICmdCmdGdbShow::ms_mapGdbOptionNameToFnGdbOptionPtr = {
30         {"target-async", &CMICmdCmdGdbShow::OptionFnTargetAsync},
31         {"print", &CMICmdCmdGdbShow::OptionFnPrint},
32         {"language", &CMICmdCmdGdbShow::OptionFnLanguage},
33         {"disassembly-flavor", &CMICmdCmdGdbShow::OptionFnDisassemblyFlavor},
34         {"fallback", &CMICmdCmdGdbShow::OptionFnFallback},
35         {"breakpoint", &CMICmdCmdGdbShow::OptionFnBreakpoint}};
36
37 //++
38 // Details: CMICmdCmdGdbShow constructor.
39 // Type:    Method.
40 // Args:    None.
41 // Return:  None.
42 // Throws:  None.
43 //--
44 CMICmdCmdGdbShow::CMICmdCmdGdbShow()
45     : m_constStrArgNamedGdbOption("option"), m_bGdbOptionRecognised(true),
46       m_bGdbOptionFnSuccessful(false), m_bGbbOptionFnHasError(false),
47       m_strGdbOptionFnError(MIRSRC(IDS_WORD_ERR_MSG_NOT_IMPLEMENTED_BRKTS)) {
48   // Command factory matches this name with that received from the stdin stream
49   m_strMiCmd = "gdb-show";
50
51   // Required by the CMICmdFactory when registering *this command
52   m_pSelfCreatorFn = &CMICmdCmdGdbShow::CreateSelf;
53 }
54
55 //++
56 // Details: CMICmdCmdGdbShow destructor.
57 // Type:    Overrideable.
58 // Args:    None.
59 // Return:  None.
60 // Throws:  None.
61 //--
62 CMICmdCmdGdbShow::~CMICmdCmdGdbShow() {}
63
64 //++
65 // Details: The invoker requires this function. The parses the command line
66 // options
67 //          arguments to extract values for each of those arguments.
68 // Type:    Overridden.
69 // Args:    None.
70 // Return:  MIstatus::success - Function succeeded.
71 //          MIstatus::failure - Function failed.
72 // Throws:  None.
73 //--
74 bool CMICmdCmdGdbShow::ParseArgs() {
75   m_setCmdArgs.Add(new CMICmdArgValListOfN(
76       m_constStrArgNamedGdbOption, true, true,
77       CMICmdArgValListBase::eArgValType_StringAnything));
78   return ParseValidateCmdOptions();
79 }
80
81 //++
82 // Details: The invoker requires this function. The command is executed in this
83 // function.
84 // Type:    Overridden.
85 // Args:    None.
86 // Return:  MIstatus::success - Function succeeded.
87 //          MIstatus::failure - Function failed.
88 // Throws:  None.
89 //--
90 bool CMICmdCmdGdbShow::Execute() {
91   CMICMDBASE_GETOPTION(pArgGdbOption, ListOfN, m_constStrArgNamedGdbOption);
92   const CMICmdArgValListBase::VecArgObjPtr_t &rVecWords(
93       pArgGdbOption->GetExpectedOptions());
94
95   // Get the gdb-show option to carry out. This option will be used as an action
96   // which should be done. Further arguments will be used as parameters for it.
97   CMICmdArgValListBase::VecArgObjPtr_t::const_iterator it = rVecWords.begin();
98   const CMICmdArgValString *pOption =
99       static_cast<const CMICmdArgValString *>(*it);
100   const CMIUtilString strOption(pOption->GetValue());
101   ++it;
102
103   // Retrieve the parameter(s) for the option
104   CMIUtilString::VecString_t vecWords;
105   while (it != rVecWords.end()) {
106     const CMICmdArgValString *pWord =
107         static_cast<const CMICmdArgValString *>(*it);
108     vecWords.push_back(pWord->GetValue());
109
110     // Next
111     ++it;
112   }
113
114   FnGdbOptionPtr pPrintRequestFn = nullptr;
115   if (!GetOptionFn(strOption, pPrintRequestFn)) {
116     // For unimplemented option handlers, fallback to a generic handler
117     // ToDo: Remove this when ALL options have been implemented
118     if (!GetOptionFn("fallback", pPrintRequestFn)) {
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
134 // Result
135 //          for the work carried out in the Execute() method.
136 // Type:    Overridden.
137 // Args:    None.
138 // Return:  MIstatus::success - Function succeeded.
139 //          MIstatus::failure - Function failed.
140 // Throws:  None.
141 //--
142 bool CMICmdCmdGdbShow::Acknowledge() {
143   // Print error if option isn't recognized:
144   // ^error,msg="The request '%s' was not recognized, not implemented"
145   if (!m_bGdbOptionRecognised) {
146     const CMICmnMIValueConst miValueConst(
147         CMIUtilString::Format(MIRSRC(IDS_CMD_ERR_INFO_PRINTFN_NOT_FOUND),
148                               m_strGdbOptionName.c_str()));
149     const CMICmnMIValueResult miValueResult("msg", miValueConst);
150     const CMICmnMIResultRecord miRecordResult(
151         m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Error,
152         miValueResult);
153     m_miResultRecord = miRecordResult;
154     return MIstatus::success;
155   }
156
157   // ^done,value="%s"
158   if (m_bGdbOptionFnSuccessful && !m_strValue.empty()) {
159     const CMICmnMIValueConst miValueConst(m_strValue);
160     const CMICmnMIValueResult miValueResult("value", miValueConst);
161     const CMICmnMIResultRecord miRecordResult(
162         m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Done,
163         miValueResult);
164     m_miResultRecord = miRecordResult;
165     return MIstatus::success;
166   } else if (m_bGdbOptionFnSuccessful) {
167     // Ignore empty value (for fallback)
168     const CMICmnMIResultRecord miRecordResult(
169         m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Done);
170     m_miResultRecord = miRecordResult;
171     return MIstatus::success;
172   }
173
174   // Print error if request failed:
175   // ^error,msg="The request '%s' failed.
176   const CMICmnMIValueConst miValueConst(CMIUtilString::Format(
177       MIRSRC(IDS_CMD_ERR_INFO_PRINTFN_FAILED), m_strGdbOptionFnError.c_str()));
178   const CMICmnMIValueResult miValueResult("msg", miValueConst);
179   const CMICmnMIResultRecord miRecordResult(
180       m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Error,
181       miValueResult);
182   m_miResultRecord = miRecordResult;
183
184   return MIstatus::success;
185 }
186
187 //++
188 // Details: Required by the CMICmdFactory when registering *this command. The
189 // factory
190 //          calls this function to create an instance of *this command.
191 // Type:    Static method.
192 // Args:    None.
193 // Return:  CMICmdBase * - Pointer to a new command.
194 // Throws:  None.
195 //--
196 CMICmdBase *CMICmdCmdGdbShow::CreateSelf() { return new CMICmdCmdGdbShow(); }
197
198 //++
199 // Details: Retrieve the print function's pointer for the matching print
200 // request.
201 // Type:    Method.
202 // Args:    vrPrintFnName   - (R) The info requested.
203 //          vrwpFn          - (W) The print function's pointer of the function
204 //          to carry out
205 // Return:  bool    - True = Print request is implemented, false = not found.
206 // Throws:  None.
207 //--
208 bool CMICmdCmdGdbShow::GetOptionFn(const CMIUtilString &vrPrintFnName,
209                                    FnGdbOptionPtr &vrwpFn) const {
210   vrwpFn = nullptr;
211
212   const MapGdbOptionNameToFnGdbOptionPtr_t::const_iterator it =
213       ms_mapGdbOptionNameToFnGdbOptionPtr.find(vrPrintFnName);
214   if (it != ms_mapGdbOptionNameToFnGdbOptionPtr.end()) {
215     vrwpFn = (*it).second;
216     return true;
217   }
218
219   return false;
220 }
221
222 //++
223 // Details: Carry out work to complete the GDB show option 'target-async' to
224 // prepare
225 //          and send back the requested information.
226 // Type:    Method.
227 // Args:    vrWords - (R) List of additional parameters used by this option.
228 // Return:  MIstatus::success - Function succeeded.
229 //          MIstatus::failure - Function failed.
230 // Throws:  None.
231 //--
232 bool CMICmdCmdGdbShow::OptionFnTargetAsync(
233     const CMIUtilString::VecString_t &vrWords) {
234   MIunused(vrWords);
235
236   // Get async mode
237   CMICmnLLDBDebugSessionInfo &rSessionInfo(
238       CMICmnLLDBDebugSessionInfo::Instance());
239   const bool bAsyncMode = rSessionInfo.GetDebugger().GetAsync();
240
241   m_strValue = bAsyncMode ? "on" : "off";
242   return MIstatus::success;
243 }
244
245 //++
246 // Details: Carry out work to complete the GDB show option 'print' to prepare
247 // and send
248 //          back the requested information.
249 // Type:    Method.
250 // Args:    vrWords - (R) List of additional parameters used by this option.
251 // Return:  MIstatus::success - Function succeeded.
252 //          MIstatus::failure - Function failed.
253 // Throws:  None.
254 //--
255 bool CMICmdCmdGdbShow::OptionFnPrint(
256     const CMIUtilString::VecString_t &vrWords) {
257   const bool bAllArgs(vrWords.size() == 1);
258   if (!bAllArgs) {
259     m_bGbbOptionFnHasError = true;
260     m_strGdbOptionFnError = MIRSRC(IDS_CMD_ERR_GDBSHOW_OPT_PRINT_BAD_ARGS);
261     return MIstatus::failure;
262   }
263
264   const CMIUtilString strOption(vrWords[0]);
265   CMIUtilString strOptionKey;
266   bool bOptionValueDefault = false;
267   if (CMIUtilString::Compare(strOption, "char-array-as-string"))
268     strOptionKey = m_rLLDBDebugSessionInfo.m_constStrPrintCharArrayAsString;
269   else if (CMIUtilString::Compare(strOption, "expand-aggregates"))
270     strOptionKey = m_rLLDBDebugSessionInfo.m_constStrPrintExpandAggregates;
271   else if (CMIUtilString::Compare(strOption, "aggregate-field-names")) {
272     strOptionKey = m_rLLDBDebugSessionInfo.m_constStrPrintAggregateFieldNames;
273     bOptionValueDefault = true;
274   } else {
275     m_bGbbOptionFnHasError = true;
276     m_strGdbOptionFnError = CMIUtilString::Format(
277         MIRSRC(IDS_CMD_ERR_GDBSHOW_OPT_PRINT_UNKNOWN_OPTION),
278         strOption.c_str());
279     return MIstatus::failure;
280   }
281
282   bool bOptionValue = false;
283   bOptionValue = bOptionValueDefault
284                      ? !m_rLLDBDebugSessionInfo.SharedDataRetrieve<bool>(
285                            strOptionKey, bOptionValue) ||
286                            bOptionValue
287                      : m_rLLDBDebugSessionInfo.SharedDataRetrieve<bool>(
288                            strOptionKey, bOptionValue) &&
289                            bOptionValue;
290
291   m_strValue = bOptionValue ? "on" : "off";
292   return MIstatus::success;
293 }
294
295 //++
296 // Details: Carry out work to complete the GDB show option 'language' to prepare
297 //          and send back the requested information.
298 // Type:    Method.
299 // Args:    vrWords - (R) List of additional parameters used by this option.
300 // Return:  MIstatus::success - Function succeeded.
301 //          MIstatus::failure - Function failed.
302 // Throws:  None.
303 //--
304 bool CMICmdCmdGdbShow::OptionFnLanguage(
305     const CMIUtilString::VecString_t &vrWords) {
306   MIunused(vrWords);
307
308   // Get current language
309   CMICmnLLDBDebugSessionInfo &rSessionInfo(
310       CMICmnLLDBDebugSessionInfo::Instance());
311   lldb::SBThread sbThread = rSessionInfo.GetProcess().GetSelectedThread();
312   const lldb::SBFrame sbFrame = sbThread.GetSelectedFrame();
313   lldb::SBCompileUnit sbCompileUnit = sbFrame.GetCompileUnit();
314   const lldb::LanguageType eLanguageType = sbCompileUnit.GetLanguage();
315
316   m_strValue = lldb::SBLanguageRuntime::GetNameForLanguageType(eLanguageType);
317   return MIstatus::success;
318 }
319
320 //++
321 // Details: Carry out work to complete the GDB show option 'disassembly-flavor' to prepare
322 //          and send back the requested information.
323 // Type:    Method.
324 // Args:    vrWords - (R) List of additional parameters used by this option.
325 // Return:  MIstatus::success - Function succeeded.
326 //          MIstatus::failure - Function failed.
327 // Throws:  None.
328 //--
329 bool CMICmdCmdGdbShow::OptionFnDisassemblyFlavor(const CMIUtilString::VecString_t &vrWords) {
330   MIunused(vrWords);
331
332   // Get current disassembly flavor
333   lldb::SBDebugger &rDbgr = m_rLLDBDebugSessionInfo.GetDebugger();
334   m_strValue = lldb::SBDebugger::GetInternalVariableValue("target.x86-disassembly-flavor",
335                                                           rDbgr.GetInstanceName()).GetStringAtIndex(0);
336   return MIstatus::success;
337 }
338
339 //++
340 // Details: Carry out work to complete the GDB show option 'breakpoint' to
341 // prepare
342 //          and send back the requested information.
343 // Type:    Method.
344 // Args:    vrWords - (R) List of additional parameters used by this option.
345 // Return:  MIstatus::success - Function succeeded.
346 //          MIstatus::failure - Function failed.
347 // Throws:  None.
348 //--
349 bool CMICmdCmdGdbShow::OptionFnBreakpoint(
350     const CMIUtilString::VecString_t &vrWords) {
351   if (vrWords.size() != 1) {
352     m_bGbbOptionFnHasError = true;
353     m_strGdbOptionFnError = MIRSRC(IDS_CMD_ERR_GDBSHOW_OPT_BREAKPOINT_BAD_ARGS);
354     return MIstatus::failure;
355   }
356
357   const CMIUtilString strOption(vrWords[0]);
358   if (!CMIUtilString::Compare(strOption, "pending")) {
359     m_bGbbOptionFnHasError = true;
360     m_strGdbOptionFnError = CMIUtilString::Format(
361         MIRSRC(IDS_CMD_ERR_GDBSHOW_OPT_BREAKPOINT_UNKNOWN_OPTION),
362         strOption.c_str());
363     return MIstatus::failure;
364   }
365
366   if (!m_rLLDBDebugSessionInfo.SharedDataRetrieve("breakpoint.pending",
367                                                   m_strValue)) {
368     if (m_strValue.empty())
369       m_strValue = "off";
370   }
371
372   return MIstatus::success;
373 }
374
375 //++
376 // Details: Carry out work to complete the GDB show option to prepare and send
377 // back the
378 //          requested information.
379 // Type:    Method.
380 // Args:    None.
381 // Return:  MIstatus::success - Function succeeded.
382 //          MIstatus::failure - Function failed.
383 // Throws:  None.
384 //--
385 bool CMICmdCmdGdbShow::OptionFnFallback(
386     const CMIUtilString::VecString_t &vrWords) {
387   MIunused(vrWords);
388
389   // Do nothing - intentional. This is a fallback function to do nothing.
390   // This allows the search for gdb-show options to always succeed when the
391   // option is not
392   // found (implemented).
393
394   return MIstatus::success;
395 }