1 //===-- MICmdCmdGdbInfo.cpp -------------------------------------*- C++ -*-===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 // Overview: CMICmdCmdGdbInfo implementation.
12 // Third party headers:
13 #include "lldb/API/SBCommandReturnObject.h"
14 #include <inttypes.h> // For PRIx64
17 #include "MICmdArgValString.h"
18 #include "MICmdCmdGdbInfo.h"
19 #include "MICmnLLDBDebugSessionInfo.h"
20 #include "MICmnMIResultRecord.h"
21 #include "MICmnMIValueConst.h"
22 #include "MICmnStreamStdout.h"
25 const CMICmdCmdGdbInfo::MapPrintFnNameToPrintFn_t
26 CMICmdCmdGdbInfo::ms_mapPrintFnNameToPrintFn = {
27 {"sharedlibrary", &CMICmdCmdGdbInfo::PrintFnSharedLibrary}};
30 //------------------------------------------------------------------------------------
31 // Details: CMICmdCmdGdbInfo constructor.
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
44 // Required by the CMICmdFactory when registering *this command
45 m_pSelfCreatorFn = &CMICmdCmdGdbInfo::CreateSelf;
49 //------------------------------------------------------------------------------------
50 // Details: CMICmdCmdGdbInfo destructor.
51 // Type: Overrideable.
56 CMICmdCmdGdbInfo::~CMICmdCmdGdbInfo() {}
59 //------------------------------------------------------------------------------------
60 // Details: The invoker requires this function. The parses the command line
62 // arguments to extract values for each of those arguments.
65 // Return: MIstatus::success - Functional succeeded.
66 // MIstatus::failure - Functional failed.
69 bool CMICmdCmdGdbInfo::ParseArgs() {
70 m_setCmdArgs.Add(new CMICmdArgValString(m_constStrArgNamedPrint, true, true));
71 return ParseValidateCmdOptions();
75 //------------------------------------------------------------------------------------
76 // Details: The invoker requires this function. The command does work in this
78 // The command is likely to communicate with the LLDB SBDebugger in
82 // Return: MIstatus::success - Functional succeeded.
83 // MIstatus::failure - Functional failed.
86 bool CMICmdCmdGdbInfo::Execute() {
87 CMICMDBASE_GETOPTION(pArgPrint, String, m_constStrArgNamedPrint);
88 const CMIUtilString &rPrintRequest(pArgPrint->GetValue());
90 FnPrintPtr pPrintRequestFn = nullptr;
91 if (!GetPrintFn(rPrintRequest, pPrintRequestFn)) {
92 m_strPrintFnName = rPrintRequest;
93 m_bPrintFnRecognised = false;
94 return MIstatus::success;
97 m_bPrintFnSuccessful = (this->*(pPrintRequestFn))();
99 return MIstatus::success;
103 //------------------------------------------------------------------------------------
104 // Details: The invoker requires this function. The command prepares a MI Record
106 // for the work carried out in the Execute().
109 // Return: MIstatus::success - Functional succeeded.
110 // MIstatus::failure - Functional failed.
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,
121 m_miResultRecord = miRecordResult;
122 return MIstatus::success;
125 if (m_bPrintFnSuccessful) {
126 const CMICmnMIResultRecord miRecordResult(
127 m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Done);
128 m_miResultRecord = miRecordResult;
129 return MIstatus::success;
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,
138 m_miResultRecord = miRecordResult;
140 return MIstatus::success;
144 //------------------------------------------------------------------------------------
145 // Details: Required by the CMICmdFactory when registering *this command. The
147 // calls this function to create an instance of *this command.
148 // Type: Static method.
150 // Return: CMICmdBase * - Pointer to a new command.
153 CMICmdBase *CMICmdCmdGdbInfo::CreateSelf() { return new CMICmdCmdGdbInfo(); }
156 //------------------------------------------------------------------------------------
157 // Details: Retrieve the print function's pointer for the matching print
160 // Args: vrPrintFnName - (R) The info requested.
161 // vrwpFn - (W) The print function's pointer of the function
163 // Return: bool - True = Print request is implemented, false = not found.
166 bool CMICmdCmdGdbInfo::GetPrintFn(const CMIUtilString &vrPrintFnName,
167 FnPrintPtr &vrwpFn) const {
170 const MapPrintFnNameToPrintFn_t::const_iterator it =
171 ms_mapPrintFnNameToPrintFn.find(vrPrintFnName);
172 if (it != ms_mapPrintFnNameToPrintFn.end()) {
173 vrwpFn = (*it).second;
181 //------------------------------------------------------------------------------------
182 // Details: Carry out work to complete the request to prepare and send back
187 // Return: MIstatus::success - Functional succeeded.
188 // MIstatus::failure - Functional failed.
191 bool CMICmdCmdGdbInfo::PrintFnSharedLibrary() {
192 bool bOk = CMICmnStreamStdout::TextToStdout(
193 "~\"From To Syms Read Shared Object Library\"");
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;
222 addrLoadSize += section.GetByteSize();
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()));