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 //===----------------------------------------------------------------------===//
11 // File: MICmdCmdGdbInfo.cpp
13 // Overview: CMICmdCmdGdbInfo implementation.
15 // Environment: Compilers: Visual C++ 12.
16 // gcc (Ubuntu/Linaro 4.8.1-10ubuntu9) 4.8.1
17 // Libraries: See MIReadmetxt.
22 // Third party headers:
23 #include <lldb/API/SBCommandReturnObject.h>
26 #include "MICmdCmdGdbInfo.h"
27 #include "MICmnMIResultRecord.h"
28 #include "MICmnMIValueConst.h"
29 #include "MICmdArgValString.h"
30 #include "MICmnStreamStdout.h"
31 #include "MICmnLLDBDebugSessionInfo.h"
34 const CMICmdCmdGdbInfo::MapPrintFnNameToPrintFn_t CMICmdCmdGdbInfo::ms_mapPrintFnNameToPrintFn =
36 { "sharedlibrary", &CMICmdCmdGdbInfo::PrintFnSharedLibrary }
39 //++ ------------------------------------------------------------------------------------
40 // Details: CMICmdCmdGdbInfo constructor.
46 CMICmdCmdGdbInfo::CMICmdCmdGdbInfo( void )
47 : m_constStrArgNamedPrint( "print" )
48 , m_bPrintFnRecognised( true )
49 , m_bPrintFnSuccessful( false )
50 , m_strPrintFnError( MIRSRC( IDS_WORD_ERR_MSG_NOT_IMPLEMENTED_BRKTS ) )
52 // Command factory matches this name with that received from the stdin stream
55 // Required by the CMICmdFactory when registering *this command
56 m_pSelfCreatorFn = &CMICmdCmdGdbInfo::CreateSelf;
59 //++ ------------------------------------------------------------------------------------
60 // Details: CMICmdCmdGdbInfo destructor.
61 // Type: Overrideable.
66 CMICmdCmdGdbInfo::~CMICmdCmdGdbInfo( void )
70 //++ ------------------------------------------------------------------------------------
71 // Details: The invoker requires this function. The parses the command line options
72 // arguments to extract values for each of those arguments.
75 // Return: MIstatus::success - Functional succeeded.
76 // MIstatus::failure - Functional failed.
79 bool CMICmdCmdGdbInfo::ParseArgs( void )
81 bool bOk = m_setCmdArgs.Add( *(new CMICmdArgValString( m_constStrArgNamedPrint, true, true ) ) );
82 return (bOk && ParseValidateCmdOptions() );
85 //++ ------------------------------------------------------------------------------------
86 // Details: The invoker requires this function. The command does work in this function.
87 // The command is likely to communicate with the LLDB SBDebugger in here.
90 // Return: MIstatus::success - Functional succeeded.
91 // MIstatus::failure - Functional failed.
94 bool CMICmdCmdGdbInfo::Execute( void )
96 CMICMDBASE_GETOPTION( pArgPrint, String, m_constStrArgNamedPrint );
97 const CMIUtilString & rPrintRequest( pArgPrint->GetValue() );
99 FnPrintPtr pPrintRequestFn = nullptr;
100 if( !GetPrintFn( rPrintRequest, pPrintRequestFn ) )
102 m_strPrintFnName = rPrintRequest;
103 m_bPrintFnRecognised = false;
104 return MIstatus::success;
107 m_bPrintFnSuccessful = (this->*(pPrintRequestFn))();
109 return MIstatus::success;
112 //++ ------------------------------------------------------------------------------------
113 // Details: The invoker requires this function. The command prepares a MI Record Result
114 // for the work carried out in the Execute().
117 // Return: MIstatus::success - Functional succeeded.
118 // MIstatus::failure - Functional failed.
121 bool CMICmdCmdGdbInfo::Acknowledge( void )
123 if( !m_bPrintFnRecognised )
125 const CMICmnMIValueConst miValueConst( CMIUtilString::Format( MIRSRC( IDS_CMD_ERR_INFO_PRINTFN_NOT_FOUND ), m_strPrintFnName.c_str() ) );
126 const CMICmnMIValueResult miValueResult( "msg", miValueConst );
127 const CMICmnMIResultRecord miRecordResult( m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Error, miValueResult );
128 m_miResultRecord = miRecordResult;
129 return MIstatus::success;
132 if( m_bPrintFnSuccessful )
134 const CMICmnMIResultRecord miRecordResult( m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Done );
135 m_miResultRecord = miRecordResult;
136 return MIstatus::success;
139 const CMICmnMIValueConst miValueConst( CMIUtilString::Format( MIRSRC( IDS_CMD_ERR_INFO_PRINTFN_FAILED ), m_strPrintFnError.c_str() ) );
140 const CMICmnMIValueResult miValueResult( "msg", miValueConst );
141 const CMICmnMIResultRecord miRecordResult( m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Error, miValueResult );
142 m_miResultRecord = miRecordResult;
144 return MIstatus::success;
147 //++ ------------------------------------------------------------------------------------
148 // Details: Required by the CMICmdFactory when registering *this command. The factory
149 // calls this function to create an instance of *this command.
150 // Type: Static method.
152 // Return: CMICmdBase * - Pointer to a new command.
155 CMICmdBase * CMICmdCmdGdbInfo::CreateSelf( void )
157 return new CMICmdCmdGdbInfo();
160 //++ ------------------------------------------------------------------------------------
161 // Details: Retrieve the print function's pointer for the matching print request.
163 // Args: vrPrintFnName - (R) The info requested.
164 // vrwpFn - (W) The print function's pointer of the function to carry out
165 // Return: bool - True = Print request is implemented, false = not found.
168 bool CMICmdCmdGdbInfo::GetPrintFn( const CMIUtilString & vrPrintFnName, FnPrintPtr & vrwpFn ) const
172 const MapPrintFnNameToPrintFn_t::const_iterator it = ms_mapPrintFnNameToPrintFn.find( vrPrintFnName );
173 if( it != ms_mapPrintFnNameToPrintFn.end() )
175 vrwpFn = (*it).second;
182 //++ ------------------------------------------------------------------------------------
183 // Details: Carry out work to complete the request to prepare and send back information
187 // Return: MIstatus::success - Functional succeeded.
188 // MIstatus::failure - Functional failed.
191 bool CMICmdCmdGdbInfo::PrintFnSharedLibrary( void )
193 CMICmnStreamStdout & rStdout = CMICmnStreamStdout::Instance();
194 bool bOk = rStdout.TextToStdout( "~\"From To Syms Read Shared Object Library\"" );
196 CMICmnLLDBDebugSessionInfo & rSessionInfo( CMICmnLLDBDebugSessionInfo::Instance() );
197 lldb::SBTarget & rTarget = rSessionInfo.m_lldbTarget;
198 const MIuint nModules = rTarget.GetNumModules();
199 for( MIuint i = 0; bOk && (i < nModules); i++ )
201 lldb::SBModule module = rTarget.GetModuleAtIndex( i );
202 if( module.IsValid() )
204 const CMIUtilString strModuleFilePath( module.GetFileSpec().GetDirectory() );
205 const CMIUtilString strModuleFileName( module.GetFileSpec().GetFilename() );
206 const CMIUtilString strModuleFullPath( CMIUtilString::Format( "%s/%s", strModuleFilePath.c_str(), strModuleFileName.c_str() ) );
207 const CMIUtilString strHasSymbols = (module.GetNumSymbols() > 0) ? "Yes" : "No";
208 lldb::addr_t addrLoadS = 0xffffffff;
209 lldb::addr_t addrLoadSize = 0;
210 bool bHaveAddrLoad = false;
211 const MIuint nSections = module.GetNumSections();
212 for( MIuint j = 0; j < nSections; j++ )
214 lldb::SBSection section = module.GetSectionAtIndex( j );
215 lldb::addr_t addrLoad = section.GetLoadAddress( rTarget );
216 if( addrLoad != (lldb::addr_t) -1 )
220 bHaveAddrLoad = true;
221 addrLoadS = addrLoad;
224 addrLoadSize += section.GetByteSize();
227 bOk = bOk && rStdout.TextToStdout( CMIUtilString::Format( "~\"0x%08x\t0x%08x\t%s\t\t%s\"", addrLoadS, addrLoadS + addrLoadSize, strHasSymbols.c_str(), strModuleFullPath.c_str() ) );