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