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