1 //===-- MICmdCmdGdbInfo.cpp -------------------------------------*- C++ -*-===//
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
7 //===----------------------------------------------------------------------===//
9 // Overview: CMICmdCmdGdbInfo implementation.
11 // Third party headers:
12 #include "lldb/API/SBCommandReturnObject.h"
16 #include "MICmdArgValString.h"
17 #include "MICmdCmdGdbInfo.h"
18 #include "MICmnLLDBDebugSessionInfo.h"
19 #include "MICmnMIResultRecord.h"
20 #include "MICmnMIValueConst.h"
21 #include "MICmnStreamStdout.h"
24 const CMICmdCmdGdbInfo::MapPrintFnNameToPrintFn_t
25 CMICmdCmdGdbInfo::ms_mapPrintFnNameToPrintFn = {
26 {"sharedlibrary", &CMICmdCmdGdbInfo::PrintFnSharedLibrary}};
29 // Details: CMICmdCmdGdbInfo constructor.
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
42 // Required by the CMICmdFactory when registering *this command
43 m_pSelfCreatorFn = &CMICmdCmdGdbInfo::CreateSelf;
47 // Details: CMICmdCmdGdbInfo destructor.
48 // Type: Overrideable.
53 CMICmdCmdGdbInfo::~CMICmdCmdGdbInfo() {}
56 // Details: The invoker requires this function. The parses the command line
58 // arguments to extract values for each of those arguments.
61 // Return: MIstatus::success - Functional succeeded.
62 // MIstatus::failure - Functional failed.
65 bool CMICmdCmdGdbInfo::ParseArgs() {
66 m_setCmdArgs.Add(new CMICmdArgValString(m_constStrArgNamedPrint, true, true));
67 return ParseValidateCmdOptions();
71 // Details: The invoker requires this function. The command does work in this
73 // The command is likely to communicate with the LLDB SBDebugger in
77 // Return: MIstatus::success - Functional succeeded.
78 // MIstatus::failure - Functional failed.
81 bool CMICmdCmdGdbInfo::Execute() {
82 CMICMDBASE_GETOPTION(pArgPrint, String, m_constStrArgNamedPrint);
83 const CMIUtilString &rPrintRequest(pArgPrint->GetValue());
85 FnPrintPtr pPrintRequestFn = nullptr;
86 if (!GetPrintFn(rPrintRequest, pPrintRequestFn)) {
87 m_strPrintFnName = rPrintRequest;
88 m_bPrintFnRecognised = false;
89 return MIstatus::success;
92 m_bPrintFnSuccessful = (this->*(pPrintRequestFn))();
94 return MIstatus::success;
98 // Details: The invoker requires this function. The command prepares a MI Record
100 // for the work carried out in the Execute().
103 // Return: MIstatus::success - Functional succeeded.
104 // MIstatus::failure - Functional failed.
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,
115 m_miResultRecord = miRecordResult;
116 return MIstatus::success;
119 if (m_bPrintFnSuccessful) {
120 const CMICmnMIResultRecord miRecordResult(
121 m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Done);
122 m_miResultRecord = miRecordResult;
123 return MIstatus::success;
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,
132 m_miResultRecord = miRecordResult;
134 return MIstatus::success;
138 // Details: Required by the CMICmdFactory when registering *this command. The
140 // calls this function to create an instance of *this command.
141 // Type: Static method.
143 // Return: CMICmdBase * - Pointer to a new command.
146 CMICmdBase *CMICmdCmdGdbInfo::CreateSelf() { return new CMICmdCmdGdbInfo(); }
149 // Details: Retrieve the print function's pointer for the matching print
152 // Args: vrPrintFnName - (R) The info requested.
153 // vrwpFn - (W) The print function's pointer of the function
155 // Return: bool - True = Print request is implemented, false = not found.
158 bool CMICmdCmdGdbInfo::GetPrintFn(const CMIUtilString &vrPrintFnName,
159 FnPrintPtr &vrwpFn) const {
162 const MapPrintFnNameToPrintFn_t::const_iterator it =
163 ms_mapPrintFnNameToPrintFn.find(vrPrintFnName);
164 if (it != ms_mapPrintFnNameToPrintFn.end()) {
165 vrwpFn = (*it).second;
173 // Details: Carry out work to complete the request to prepare and send back
178 // Return: MIstatus::success - Functional succeeded.
179 // MIstatus::failure - Functional failed.
182 bool CMICmdCmdGdbInfo::PrintFnSharedLibrary() {
183 bool bOk = CMICmnStreamStdout::TextToStdout(
184 "~\"From To Syms Read Shared Object Library\"");
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;
213 addrLoadSize += section.GetByteSize();
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()));