]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/llvm-project/lldb/tools/lldb-mi/MICmdCmdGdbInfo.cpp
Merge llvm, clang, compiler-rt, libc++, libunwind, lld, lldb and openmp
[FreeBSD/FreeBSD.git] / contrib / llvm-project / lldb / tools / lldb-mi / MICmdCmdGdbInfo.cpp
1 //===-- MICmdCmdGdbInfo.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:    CMICmdCmdGdbInfo        implementation.
10
11 // Third party headers:
12 #include "lldb/API/SBCommandReturnObject.h"
13 #include <inttypes.h>
14
15 // In-house headers:
16 #include "MICmdArgValString.h"
17 #include "MICmdCmdGdbInfo.h"
18 #include "MICmnLLDBDebugSessionInfo.h"
19 #include "MICmnMIResultRecord.h"
20 #include "MICmnMIValueConst.h"
21 #include "MICmnStreamStdout.h"
22
23 // Instantiations:
24 const CMICmdCmdGdbInfo::MapPrintFnNameToPrintFn_t
25     CMICmdCmdGdbInfo::ms_mapPrintFnNameToPrintFn = {
26         {"sharedlibrary", &CMICmdCmdGdbInfo::PrintFnSharedLibrary}};
27
28 //++
29 // Details: CMICmdCmdGdbInfo constructor.
30 // Type:    Method.
31 // Args:    None.
32 // Return:  None.
33 // Throws:  None.
34 //--
35 CMICmdCmdGdbInfo::CMICmdCmdGdbInfo()
36     : m_constStrArgNamedPrint("print"), m_bPrintFnRecognised(true),
37       m_bPrintFnSuccessful(false),
38       m_strPrintFnError(MIRSRC(IDS_WORD_ERR_MSG_NOT_IMPLEMENTED_BRKTS)) {
39   // Command factory matches this name with that received from the stdin stream
40   m_strMiCmd = "info";
41
42   // Required by the CMICmdFactory when registering *this command
43   m_pSelfCreatorFn = &CMICmdCmdGdbInfo::CreateSelf;
44 }
45
46 //++
47 // Details: CMICmdCmdGdbInfo destructor.
48 // Type:    Overrideable.
49 // Args:    None.
50 // Return:  None.
51 // Throws:  None.
52 //--
53 CMICmdCmdGdbInfo::~CMICmdCmdGdbInfo() {}
54
55 //++
56 // Details: The invoker requires this function. The parses the command line
57 // options
58 //          arguments to extract values for each of those arguments.
59 // Type:    Overridden.
60 // Args:    None.
61 // Return:  MIstatus::success - Functional succeeded.
62 //          MIstatus::failure - Functional failed.
63 // Throws:  None.
64 //--
65 bool CMICmdCmdGdbInfo::ParseArgs() {
66   m_setCmdArgs.Add(new CMICmdArgValString(m_constStrArgNamedPrint, true, true));
67   return ParseValidateCmdOptions();
68 }
69
70 //++
71 // Details: The invoker requires this function. The command does work in this
72 // function.
73 //          The command is likely to communicate with the LLDB SBDebugger in
74 //          here.
75 // Type:    Overridden.
76 // Args:    None.
77 // Return:  MIstatus::success - Functional succeeded.
78 //          MIstatus::failure - Functional failed.
79 // Throws:  None.
80 //--
81 bool CMICmdCmdGdbInfo::Execute() {
82   CMICMDBASE_GETOPTION(pArgPrint, String, m_constStrArgNamedPrint);
83   const CMIUtilString &rPrintRequest(pArgPrint->GetValue());
84
85   FnPrintPtr pPrintRequestFn = nullptr;
86   if (!GetPrintFn(rPrintRequest, pPrintRequestFn)) {
87     m_strPrintFnName = rPrintRequest;
88     m_bPrintFnRecognised = false;
89     return MIstatus::success;
90   }
91
92   m_bPrintFnSuccessful = (this->*(pPrintRequestFn))();
93
94   return MIstatus::success;
95 }
96
97 //++
98 // Details: The invoker requires this function. The command prepares a MI Record
99 // Result
100 //          for the work carried out in the Execute().
101 // Type:    Overridden.
102 // Args:    None.
103 // Return:  MIstatus::success - Functional succeeded.
104 //          MIstatus::failure - Functional failed.
105 // Throws:  None.
106 //--
107 bool CMICmdCmdGdbInfo::Acknowledge() {
108   if (!m_bPrintFnRecognised) {
109     const CMICmnMIValueConst miValueConst(CMIUtilString::Format(
110         MIRSRC(IDS_CMD_ERR_INFO_PRINTFN_NOT_FOUND), m_strPrintFnName.c_str()));
111     const CMICmnMIValueResult miValueResult("msg", miValueConst);
112     const CMICmnMIResultRecord miRecordResult(
113         m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Error,
114         miValueResult);
115     m_miResultRecord = miRecordResult;
116     return MIstatus::success;
117   }
118
119   if (m_bPrintFnSuccessful) {
120     const CMICmnMIResultRecord miRecordResult(
121         m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Done);
122     m_miResultRecord = miRecordResult;
123     return MIstatus::success;
124   }
125
126   const CMICmnMIValueConst miValueConst(CMIUtilString::Format(
127       MIRSRC(IDS_CMD_ERR_INFO_PRINTFN_FAILED), m_strPrintFnError.c_str()));
128   const CMICmnMIValueResult miValueResult("msg", miValueConst);
129   const CMICmnMIResultRecord miRecordResult(
130       m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Error,
131       miValueResult);
132   m_miResultRecord = miRecordResult;
133
134   return MIstatus::success;
135 }
136
137 //++
138 // Details: Required by the CMICmdFactory when registering *this command. The
139 // factory
140 //          calls this function to create an instance of *this command.
141 // Type:    Static method.
142 // Args:    None.
143 // Return:  CMICmdBase * - Pointer to a new command.
144 // Throws:  None.
145 //--
146 CMICmdBase *CMICmdCmdGdbInfo::CreateSelf() { return new CMICmdCmdGdbInfo(); }
147
148 //++
149 // Details: Retrieve the print function's pointer for the matching print
150 // request.
151 // Type:    Method.
152 // Args:    vrPrintFnName   - (R) The info requested.
153 //          vrwpFn          - (W) The print function's pointer of the function
154 //          to carry out
155 // Return:  bool    - True = Print request is implemented, false = not found.
156 // Throws:  None.
157 //--
158 bool CMICmdCmdGdbInfo::GetPrintFn(const CMIUtilString &vrPrintFnName,
159                                   FnPrintPtr &vrwpFn) const {
160   vrwpFn = nullptr;
161
162   const MapPrintFnNameToPrintFn_t::const_iterator it =
163       ms_mapPrintFnNameToPrintFn.find(vrPrintFnName);
164   if (it != ms_mapPrintFnNameToPrintFn.end()) {
165     vrwpFn = (*it).second;
166     return true;
167   }
168
169   return false;
170 }
171
172 //++
173 // Details: Carry out work to complete the request to prepare and send back
174 // information
175 //          asked for.
176 // Type:    Method.
177 // Args:    None.
178 // Return:  MIstatus::success - Functional succeeded.
179 //          MIstatus::failure - Functional failed.
180 // Throws:  None.
181 //--
182 bool CMICmdCmdGdbInfo::PrintFnSharedLibrary() {
183   bool bOk = CMICmnStreamStdout::TextToStdout(
184       "~\"From        To          Syms Read   Shared Object Library\"");
185
186   CMICmnLLDBDebugSessionInfo &rSessionInfo(
187       CMICmnLLDBDebugSessionInfo::Instance());
188   lldb::SBTarget sbTarget = rSessionInfo.GetTarget();
189   const MIuint nModules = sbTarget.GetNumModules();
190   for (MIuint i = 0; bOk && (i < nModules); i++) {
191     lldb::SBModule module = sbTarget.GetModuleAtIndex(i);
192     if (module.IsValid()) {
193       const CMIUtilString strModuleFilePath(
194           module.GetFileSpec().GetDirectory());
195       const CMIUtilString strModuleFileName(module.GetFileSpec().GetFilename());
196       const CMIUtilString strModuleFullPath(CMIUtilString::Format(
197           "%s/%s", strModuleFilePath.c_str(), strModuleFileName.c_str()));
198       const CMIUtilString strHasSymbols =
199           (module.GetNumSymbols() > 0) ? "Yes" : "No";
200       lldb::addr_t addrLoadS = 0xffffffffffffffff;
201       lldb::addr_t addrLoadSize = 0;
202       bool bHaveAddrLoad = false;
203       const MIuint nSections = module.GetNumSections();
204       for (MIuint j = 0; j < nSections; j++) {
205         lldb::SBSection section = module.GetSectionAtIndex(j);
206         lldb::addr_t addrLoad = section.GetLoadAddress(sbTarget);
207         if (addrLoad != (lldb::addr_t)-1) {
208           if (!bHaveAddrLoad) {
209             bHaveAddrLoad = true;
210             addrLoadS = addrLoad;
211           }
212
213           addrLoadSize += section.GetByteSize();
214         }
215       }
216       bOk = bOk &&
217         CMICmnStreamStdout::TextToStdout(CMIUtilString::Format(
218                 "~\"0x%016" PRIx64 "\t0x%016" PRIx64 "\t%s\t\t%s\"", addrLoadS,
219                 addrLoadS + addrLoadSize, strHasSymbols.c_str(),
220                 strModuleFullPath.c_str()));
221     }
222   }
223
224   return bOk;
225 }