]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/llvm/tools/lldb/tools/lldb-mi/MICmdCmdGdbInfo.cpp
Merge ^/head r275118 through r275209.
[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 //++
11 // File:                MICmdCmdGdbInfo.cpp
12 //
13 // Overview:    CMICmdCmdGdbInfo                implementation.
14 //
15 // Environment: Compilers:      Visual C++ 12.
16 //                                                      gcc (Ubuntu/Linaro 4.8.1-10ubuntu9) 4.8.1
17 //                              Libraries:      See MIReadmetxt. 
18 //
19 // Copyright:   None.
20 //--
21
22 // Third party headers:
23 #include <lldb/API/SBCommandReturnObject.h>
24
25 // In-house headers:
26 #include "MICmdCmdGdbInfo.h"
27 #include "MICmnMIResultRecord.h"
28 #include "MICmnMIValueConst.h"
29 #include "MICmdArgValString.h"
30 #include "MICmnStreamStdout.h"
31 #include "MICmnLLDBDebugSessionInfo.h"
32
33 // Instantiations:
34 const CMICmdCmdGdbInfo::MapPrintFnNameToPrintFn_t CMICmdCmdGdbInfo::ms_mapPrintFnNameToPrintFn = 
35 {
36         { "sharedlibrary", &CMICmdCmdGdbInfo::PrintFnSharedLibrary }
37 };
38
39 //++ ------------------------------------------------------------------------------------
40 // Details:     CMICmdCmdGdbInfo constructor.
41 // Type:        Method.
42 // Args:        None.
43 // Return:      None.
44 // Throws:      None.
45 //--
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 ) )
51 {
52         // Command factory matches this name with that received from the stdin stream
53         m_strMiCmd = "info";
54         
55         // Required by the CMICmdFactory when registering *this command
56         m_pSelfCreatorFn = &CMICmdCmdGdbInfo::CreateSelf;
57 }
58
59 //++ ------------------------------------------------------------------------------------
60 // Details:     CMICmdCmdGdbInfo destructor.
61 // Type:        Overrideable.
62 // Args:        None.
63 // Return:      None.
64 // Throws:      None.
65 //--
66 CMICmdCmdGdbInfo::~CMICmdCmdGdbInfo( void )
67 {
68 }
69
70 //++ ------------------------------------------------------------------------------------
71 // Details:     The invoker requires this function. The parses the command line options 
72 //                      arguments to extract values for each of those arguments.
73 // Type:        Overridden.
74 // Args:        None.
75 // Return:      MIstatus::success - Functional succeeded.
76 //                      MIstatus::failure - Functional failed.
77 // Throws:      None.
78 //--
79 bool CMICmdCmdGdbInfo::ParseArgs( void )
80 {
81         bool bOk = m_setCmdArgs.Add( *(new CMICmdArgValString( m_constStrArgNamedPrint, true, true ) ) );
82         return (bOk && ParseValidateCmdOptions() );
83 }
84
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.
88 // Type:        Overridden.
89 // Args:        None.
90 // Return:      MIstatus::success - Functional succeeded.
91 //                      MIstatus::failure - Functional failed.
92 // Throws:      None.
93 //--
94 bool CMICmdCmdGdbInfo::Execute( void )
95 {
96         CMICMDBASE_GETOPTION( pArgPrint, String, m_constStrArgNamedPrint );
97         const CMIUtilString & rPrintRequest( pArgPrint->GetValue() );
98
99         FnPrintPtr pPrintRequestFn = nullptr;
100         if( !GetPrintFn( rPrintRequest, pPrintRequestFn ) )
101         {
102                 m_strPrintFnName = rPrintRequest;
103                 m_bPrintFnRecognised = false;
104                 return MIstatus::success;
105         }
106         
107         m_bPrintFnSuccessful = (this->*(pPrintRequestFn))();
108
109         return MIstatus::success;
110 }
111
112 //++ ------------------------------------------------------------------------------------
113 // Details:     The invoker requires this function. The command prepares a MI Record Result
114 //                      for the work carried out in the Execute().
115 // Type:        Overridden.
116 // Args:        None.
117 // Return:      MIstatus::success - Functional succeeded.
118 //                      MIstatus::failure - Functional failed.
119 // Throws:      None.
120 //--
121 bool CMICmdCmdGdbInfo::Acknowledge( void )
122 {
123         if( !m_bPrintFnRecognised )
124         {
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;
130         }
131         
132         if( m_bPrintFnSuccessful )
133         {
134                 const CMICmnMIResultRecord miRecordResult( m_cmdData.strMiCmdToken, CMICmnMIResultRecord::eResultClass_Done );
135                 m_miResultRecord = miRecordResult;
136                 return MIstatus::success;
137         }
138
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;
143
144         return MIstatus::success;
145 }
146
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.
151 // Args:        None.
152 // Return:      CMICmdBase * - Pointer to a new command.
153 // Throws:      None.
154 //--
155 CMICmdBase * CMICmdCmdGdbInfo::CreateSelf( void )
156 {
157         return new CMICmdCmdGdbInfo();
158 }
159
160 //++ ------------------------------------------------------------------------------------
161 // Details:     Retrieve the print function's pointer for the matching print request.
162 // Type:        Method.
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.
166 // Throws:      None.
167 //--
168 bool CMICmdCmdGdbInfo::GetPrintFn( const CMIUtilString & vrPrintFnName, FnPrintPtr & vrwpFn ) const
169 {
170         vrwpFn = nullptr;
171
172         const MapPrintFnNameToPrintFn_t::const_iterator it = ms_mapPrintFnNameToPrintFn.find( vrPrintFnName );
173         if( it != ms_mapPrintFnNameToPrintFn.end() )
174         {
175                 vrwpFn = (*it).second;
176                 return true;
177         }
178
179         return false;
180 }
181         
182 //++ ------------------------------------------------------------------------------------
183 // Details:     Carry out work to complete the request to prepare and send back 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( void )
192 {
193         CMICmnStreamStdout & rStdout = CMICmnStreamStdout::Instance();
194         bool bOk = rStdout.TextToStdout( "~\"From        To          Syms Read   Shared Object Library\"" );
195
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++ )
200         {
201                 lldb::SBModule module = rTarget.GetModuleAtIndex( i );
202                 if( module.IsValid() )
203                 {
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++ )
213                         {
214                                 lldb::SBSection section = module.GetSectionAtIndex( j );
215                                 lldb::addr_t addrLoad = section.GetLoadAddress( rTarget );
216                                 if( addrLoad != (lldb::addr_t) -1 )
217                                 {
218                                         if( !bHaveAddrLoad )
219                                         {
220                                                 bHaveAddrLoad = true;
221                                                 addrLoadS = addrLoad;
222                                         }
223                                 
224                                         addrLoadSize += section.GetByteSize();
225                                 }
226                         }
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() ) );
228                 }
229         }
230
231         return bOk;
232 }