//===-- MICmdCmdGdbInfo.cpp ------------------------*- C++ -*-===// // // The LLVM Compiler Infrastructure // // This file is distributed under the University of Illinois Open Source // License. See LICENSE.TXT for details. // //===----------------------------------------------------------------------===// //++ // File: MICmdCmdGdbInfo.cpp // // Overview: CMICmdCmdGdbInfo implementation. // // Environment: Compilers: Visual C++ 12. // gcc (Ubuntu/Linaro 4.8.1-10ubuntu9) 4.8.1 // Libraries: See MIReadmetxt. // // Copyright: None. //-- // Third party headers: #include // In-house headers: #include "MICmdCmdGdbInfo.h" #include "MICmnMIResultRecord.h" #include "MICmnMIValueConst.h" #include "MICmdArgValString.h" #include "MICmnStreamStdout.h" #include "MICmnLLDBDebugSessionInfo.h" // Instantiations: const CMICmdCmdGdbInfo::MapPrintFnNameToPrintFn_t CMICmdCmdGdbInfo::ms_mapPrintFnNameToPrintFn = { { "sharedlibrary", &CMICmdCmdGdbInfo::PrintFnSharedLibrary } }; //++ ------------------------------------------------------------------------------------ // Details: CMICmdCmdGdbInfo constructor. // Type: Method. // Args: None. // Return: None. // Throws: None. //-- CMICmdCmdGdbInfo::CMICmdCmdGdbInfo( void ) : m_constStrArgNamedPrint( "print" ) , m_bPrintFnRecognised( true ) , m_bPrintFnSuccessful( false ) , m_strPrintFnError( MIRSRC( IDS_WORD_ERR_MSG_NOT_IMPLEMENTED_BRKTS ) ) { // Command factory matches this name with that received from the stdin stream m_strMiCmd = "info"; // Required by the CMICmdFactory when registering *this command m_pSelfCreatorFn = &CMICmdCmdGdbInfo::CreateSelf; } //++ ------------------------------------------------------------------------------------ // Details: CMICmdCmdGdbInfo destructor. // Type: Overrideable. // Args: None. // Return: None. // Throws: None. //-- CMICmdCmdGdbInfo::~CMICmdCmdGdbInfo( void ) { } //++ ------------------------------------------------------------------------------------ // Details: The invoker requires this function. The parses the command line options // arguments to extract values for each of those arguments. // Type: Overridden. // Args: None. // Return: MIstatus::success - Functional succeeded. // MIstatus::failure - Functional failed. // Throws: None. //-- bool CMICmdCmdGdbInfo::ParseArgs( void ) { bool bOk = m_setCmdArgs.Add( *(new CMICmdArgValString( m_constStrArgNamedPrint, true, true ) ) ); return (bOk && ParseValidateCmdOptions() ); } //++ ------------------------------------------------------------------------------------ // Details: The invoker requires this function. The command does work in this function. // The command is likely to communicate with the LLDB SBDebugger in here. // Type: Overridden. // Args: None. // Return: MIstatus::success - Functional succeeded. // MIstatus::failure - Functional failed. // Throws: None. //-- bool CMICmdCmdGdbInfo::Execute( void ) { CMICMDBASE_GETOPTION( pArgPrint, String, m_constStrArgNamedPrint ); const CMIUtilString & rPrintRequest( pArgPrint->GetValue() ); FnPrintPtr pPrintRequestFn = nullptr; if( !GetPrintFn( rPrintRequest, pPrintRequestFn ) ) { m_strPrintFnName = rPrintRequest; m_bPrintFnRecognised = false; return MIstatus::success; } m_bPrintFnSuccessful = (this->*(pPrintRequestFn))(); return MIstatus::success; } //++ ------------------------------------------------------------------------------------ // Details: The invoker requires this function. The command prepares a MI Record Result // for the work carried out in the Execute(). // Type: Overridden. // Args: None. // Return: MIstatus::success - Functional succeeded. // MIstatus::failure - Functional failed. // Throws: None. //-- bool CMICmdCmdGdbInfo::Acknowledge( void ) { if( !m_bPrintFnRecognised ) { const CMICmnMIValueConst miValueConst( CMIUtilString::Format( MIRSRC( IDS_CMD_ERR_INFO_PRINTFN_NOT_FOUND ), m_strPrintFnName.c_str() ) ); const CMICmnMIValueResult miValueResult( "msg", miValueConst ); const CMICmnMIResultRecord miRecordResult( m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Error, miValueResult ); m_miResultRecord = miRecordResult; return MIstatus::success; } if( m_bPrintFnSuccessful ) { const CMICmnMIResultRecord miRecordResult( m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Done ); m_miResultRecord = miRecordResult; return MIstatus::success; } const CMICmnMIValueConst miValueConst( CMIUtilString::Format( MIRSRC( IDS_CMD_ERR_INFO_PRINTFN_FAILED ), m_strPrintFnError.c_str() ) ); const CMICmnMIValueResult miValueResult( "msg", miValueConst ); const CMICmnMIResultRecord miRecordResult( m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Error, miValueResult ); m_miResultRecord = miRecordResult; return MIstatus::success; } //++ ------------------------------------------------------------------------------------ // Details: Required by the CMICmdFactory when registering *this command. The factory // calls this function to create an instance of *this command. // Type: Static method. // Args: None. // Return: CMICmdBase * - Pointer to a new command. // Throws: None. //-- CMICmdBase * CMICmdCmdGdbInfo::CreateSelf( void ) { return new CMICmdCmdGdbInfo(); } //++ ------------------------------------------------------------------------------------ // Details: Retrieve the print function's pointer for the matching print request. // Type: Method. // Args: vrPrintFnName - (R) The info requested. // vrwpFn - (W) The print function's pointer of the function to carry out // Return: bool - True = Print request is implemented, false = not found. // Throws: None. //-- bool CMICmdCmdGdbInfo::GetPrintFn( const CMIUtilString & vrPrintFnName, FnPrintPtr & vrwpFn ) const { vrwpFn = nullptr; const MapPrintFnNameToPrintFn_t::const_iterator it = ms_mapPrintFnNameToPrintFn.find( vrPrintFnName ); if( it != ms_mapPrintFnNameToPrintFn.end() ) { vrwpFn = (*it).second; return true; } return false; } //++ ------------------------------------------------------------------------------------ // Details: Carry out work to complete the request to prepare and send back information // asked for. // Type: Method. // Args: None. // Return: MIstatus::success - Functional succeeded. // MIstatus::failure - Functional failed. // Throws: None. //-- bool CMICmdCmdGdbInfo::PrintFnSharedLibrary( void ) { CMICmnStreamStdout & rStdout = CMICmnStreamStdout::Instance(); bool bOk = rStdout.TextToStdout( "~\"From To Syms Read Shared Object Library\"" ); CMICmnLLDBDebugSessionInfo & rSessionInfo( CMICmnLLDBDebugSessionInfo::Instance() ); lldb::SBTarget & rTarget = rSessionInfo.m_lldbTarget; const MIuint nModules = rTarget.GetNumModules(); for( MIuint i = 0; bOk && (i < nModules); i++ ) { lldb::SBModule module = rTarget.GetModuleAtIndex( i ); if( module.IsValid() ) { const CMIUtilString strModuleFilePath( module.GetFileSpec().GetDirectory() ); const CMIUtilString strModuleFileName( module.GetFileSpec().GetFilename() ); const CMIUtilString strModuleFullPath( CMIUtilString::Format( "%s/%s", strModuleFilePath.c_str(), strModuleFileName.c_str() ) ); const CMIUtilString strHasSymbols = (module.GetNumSymbols() > 0) ? "Yes" : "No"; lldb::addr_t addrLoadS = 0xffffffff; lldb::addr_t addrLoadSize = 0; bool bHaveAddrLoad = false; const MIuint nSections = module.GetNumSections(); for( MIuint j = 0; j < nSections; j++ ) { lldb::SBSection section = module.GetSectionAtIndex( j ); lldb::addr_t addrLoad = section.GetLoadAddress( rTarget ); if( addrLoad != (lldb::addr_t) -1 ) { if( !bHaveAddrLoad ) { bHaveAddrLoad = true; addrLoadS = addrLoad; } addrLoadSize += section.GetByteSize(); } } bOk = bOk && rStdout.TextToStdout( CMIUtilString::Format( "~\"0x%08x\t0x%08x\t%s\t\t%s\"", addrLoadS, addrLoadS + addrLoadSize, strHasSymbols.c_str(), strModuleFullPath.c_str() ) ); } } return bOk; }