Code::Blocks  SVN r11506
disassemblydlg.cpp
Go to the documentation of this file.
1 /*
2  * This file is part of the Code::Blocks IDE and licensed under the GNU General Public License, version 3
3  * http://www.gnu.org/licenses/gpl-3.0.html
4  *
5  * $Revision: 11350 $
6  * $Id: disassemblydlg.cpp 11350 2018-03-27 22:00:39Z fuscated $
7  * $HeadURL: https://svn.code.sf.net/p/codeblocks/code/trunk/src/src/disassemblydlg.cpp $
8  */
9 
10 #include "sdk.h"
11 
12 #include "disassemblydlg.h"
13 #ifndef CB_PRECOMP
14  #include <wx/wxscintilla.h>
15  #include <wx/intl.h>
16  #include <wx/xrc/xmlres.h>
17  #include <wx/textctrl.h>
18  #include <wx/button.h>
19  #include <wx/listctrl.h>
20  #include <wx/wfstream.h>
21  #include <wx/fontutil.h>
22  #include <wx/stattext.h>
23  #include <wx/filedlg.h>
24 
25  #include "cbproject.h"
26  #include "configmanager.h"
27  #include "editorcolourset.h"
28  #include "editormanager.h"
29  #include "globals.h"
30  #include "manager.h"
31  #include "projectmanager.h"
32 #endif
33 
34 #include "debuggermanager.h"
35 #include "filefilters.h"
36 
37 // Keep in sync with cbEditor.cpp:
38 #define DEBUG_MARKER 6
39 #define DEBUG_STYLE wxSCI_MARK_ARROW
40 
41 BEGIN_EVENT_TABLE(DisassemblyDlg, wxPanel)
42  EVT_BUTTON(XRCID("btnSave"), DisassemblyDlg::OnSave)
43 // EVT_BUTTON(XRCID("btnRefresh"), DisassemblyDlg::OnRefresh)
44  EVT_CHECKBOX(XRCID("chkMode"), DisassemblyDlg::OnMixedModeCB)
45  EVT_BUTTON(XRCID("btnAdjustLine"), DisassemblyDlg::OnAdjustLine)
46 END_EVENT_TABLE()
47 
49  m_LastActiveAddr(0),
50  m_ClearFlag(false)
51 {
52  if (!wxXmlResource::Get()->LoadPanel(this, parent, _T("dlgDisassembly")))
53  return;
54 
55  m_pCode = new wxScintilla(this, wxID_ANY, wxDefaultPosition, wxSize(1,1));
56  m_pCode->SetReadOnly(true);
57  m_pCode->SetCaretWidth(0);
58  m_pCode->SetMarginWidth(0, 0);
59  m_pCode->SetMarginType(1, wxSCI_MARGIN_SYMBOL);
60  m_pCode->SetMarginSensitive(1, 0);
61  m_pCode->SetMarginMask(1, (1 << DEBUG_MARKER));
62  m_pCode->MarkerDefine(DEBUG_MARKER, DEBUG_STYLE);
63  m_pCode->MarkerSetBackground(DEBUG_MARKER, wxColour(0xFF, 0xFF, 0x00));
64  wxXmlResource::Get()->AttachUnknownControl(_T("lcCode"), m_pCode);
65 
66  // use the same font as editor's
68  wxString fontstring = Manager::Get()->GetConfigManager(_T("editor"))->Read(_T("/font"), wxEmptyString);
69  if (!fontstring.IsEmpty())
70  {
71  wxNativeFontInfo nfi;
72  nfi.FromString(fontstring);
73  font.SetNativeFontInfo(nfi);
74  }
75  m_pCode->StyleSetFont(wxSCI_STYLE_DEFAULT, font);
76 
78  if (colour_set)
79  {
81  colour_set->Apply(lang, (cbStyledTextCtrl*)m_pCode, false, true);
82  }
83 
84  m_MixedModeCB = (wxCheckBox*)FindWindow(XRCID("chkMode"));
85  m_MixedModeCB->SetValue(Manager::Get()->GetDebuggerManager()->IsDisassemblyMixedMode());
86 
87  cbStackFrame sf;
88  Clear(sf);
89 }
90 
92 {
93  m_FrameFunction = frame.IsValid() ? frame.GetSymbol() : _T("??");
94  m_FrameAddress = _T("??");
95  if (frame.IsValid())
97 
98  m_LineTypes.clear();
99 
100  XRCCTRL(*this, "lblFunction", wxStaticText)->SetLabel(m_FrameFunction);
101  XRCCTRL(*this, "lblAddress", wxStaticText)->SetLabel(m_FrameAddress);
102 
103  m_HasActiveAddr = false;
104 
105  m_pCode->SetReadOnly(false);
106 
108 
109  if (frame.IsValid() && plugin->IsRunning())
110  {
111  // if debugger is running, show a message
112  m_pCode->SetText(_("\"Please wait while disassembling...\""));
113  m_ClearFlag = true; // clear the above message when adding the first line
114  }
115  else
116  {
117  // if debugger isn't running, just clear the window
118  m_pCode->ClearAll();
119  m_ClearFlag = false;
120  }
121  m_pCode->SetReadOnly(true);
123 }
124 
125 void DisassemblyDlg::AddAssemblerLine(uint64_t addr, const wxString& line)
126 {
127  m_pCode->SetReadOnly(false);
128  if (m_ClearFlag)
129  {
130  m_ClearFlag = false;
131  m_pCode->ClearAll();
132  }
133 
134  m_pCode->AppendText(cbDebuggerAddressToString(addr) + wxT("\t") + line + wxT("\n"));
136  m_pCode->SetReadOnly(true);
137  m_LineTypes.push_back('D') ;
138 }
139 
140 void DisassemblyDlg::AddSourceLine(int lineno, const wxString& line)
141 {
142  m_pCode->SetReadOnly(false);
143  if (m_ClearFlag)
144  {
145  m_ClearFlag = false;
146  m_pCode->ClearAll();
147  }
148  wxString fmt;
149  fmt.Printf(_T(";%-3d:\t%s\n"), lineno, line.c_str());
150 
151  m_pCode->AppendText(fmt);
152 
153  m_pCode->SetReadOnly(true);
154  m_LineTypes.push_back('S') ;
155 }
156 
158 {
159  //make line middle of display window if reasonable
160  int firstdispline ;
161  int los = m_pCode->LinesOnScreen() ;
162  if (lineno > los / 2)
163  firstdispline = lineno - (los/2) ;
164  else
165  firstdispline = 0 ; //or is it zero?
166  m_pCode->SetFirstVisibleLine(firstdispline) ;
167 }
168 
170 {
171  int displine;
172  displine = m_pCode->GetCurrentLine() ;
173  CenterLine(displine);
174 }
175 
177 {
178  if (m_HasActiveAddr && addr == m_LastActiveAddr)
179  return m_HasActiveAddr ;
180  m_HasActiveAddr = false;
181  m_LastActiveAddr = addr;
182  bool MixedAsmMode = Manager::Get()->GetDebuggerManager()->IsDisassemblyMixedMode();
183  for (int i = 0; i < m_pCode->GetLineCount() && i < int(m_LineTypes.size()); ++i)
184  {
185  if(MixedAsmMode && m_LineTypes[i] == 'S')
186  continue;
187 
188  const wxString &str = m_pCode->GetLine(i).AfterFirst(_T('x')).BeforeFirst(_T('\t'));
189  uint64_t lineaddr = cbDebuggerStringToAddress(str);
190  if (lineaddr > 0 && (lineaddr == addr))
191  {
194  m_pCode->GotoLine(i);
195 
196  //check and shift window lines if needed
197  if (!m_pCode->GetLineVisible(i))
198  {
199  this->CenterLine(i);
200  }
201  //are we close to bottom line? if so shift display if possible
202  else if (i == (m_pCode->LinesOnScreen() + m_pCode->GetFirstVisibleLine() - 1))
203  {
204  this->CenterLine(i);
205  }
206 
207  m_HasActiveAddr = true;
208  break;
209  }
210  }
211  return m_HasActiveAddr ;
212 }
213 
215 {
216  int los = m_pCode->LinesOnScreen();
217 
218  int displine;
220  displine = m_pCode->GetCurrentLine();
221  else if (m_pCode->GetCurrentLine() == m_pCode->GetFirstVisibleLine() + los/2)
222  displine = m_pCode->GetCurrentLine() - (los/2) + 1;
223  else
224  displine = m_pCode->GetCurrentLine() + (los/2);
225 
226  if (displine < 0)
227  displine = 0;
228  CenterLine(displine);
229 }
230 
232 {
233  wxFileDialog dlg(this,
234  _("Save as text file"),
235  _T("assembly_dump.txt"),
239  PlaceWindow(&dlg);
240  if (dlg.ShowModal() != wxID_OK)
241  return;
242 
243  wxString output;
245  if (prj)
246  {
247  output << _("Project title : ") << prj->GetTitle() << _T('\n');
248  output << _("Project path : ") << prj->GetBasePath() << _T('\n') << _T('\n');
249  }
250 
251  output << _("Frame function: ") << m_FrameFunction << _T('\n');
252  output << _("Frame address : ") << m_FrameAddress << _T('\n');
253  output << wxString(_T('-'), 80) << _T('\n');
254  output << m_pCode->GetText();
255 
256  if (!cbSaveToFile(dlg.GetPath(), output))
257  cbMessageBox(_("Could not save file..."), _("Error"), wxICON_ERROR);
258 }
259 
261 {
263  cbAssert(plugin);
265 }
266 
268 {
270  bool newMode = !manager.IsDisassemblyMixedMode();
271  manager.SetDisassemblyMixedMode(newMode);
272  m_MixedModeCB->SetValue(newMode);
273 
274  cbDebuggerPlugin *plugin = manager.GetActiveDebugger();
275  cbAssert(plugin);
277 }
278 
280 {
281  Enable(enable);
282 }
uint64_t m_LastActiveAddr
cbDebuggerPlugin * GetActiveDebugger()
std::vector< char > m_LineTypes
virtual int ShowModal()
bool SetActiveAddress(uint64_t addr)
void EnableWindow(bool enable)
bool FromString(const wxString &s)
ConfigManager * GetConfigManager(const wxString &name_space) const
Definition: manager.cpp:474
void AddSourceLine(int lineno, const wxString &line)
Base class for debugger plugins.
Definition: cbplugin.h:397
static Manager * Get()
Use Manager::Get() to get a pointer to its instance Manager::Get() is guaranteed to never return an i...
Definition: manager.cpp:182
#define wxSCI_MARGIN_SYMBOL
Definition: wxscintilla.h:150
void OnRefresh(wxCommandEvent &event)
#define wxICON_ERROR
class WXDLLIMPEXP_SCI wxScintilla
Definition: wxscintilla.h:2859
void AppendText(const wxString &text)
Append a string to the end of the document without changing the selection.
void OnSave(wxCommandEvent &event)
wxCStrData c_str() const
void SetText(const wxString &text)
Replace the contents of the document with the argument text.
wxString GetLine(int line) const
Retrieve the contents of a line.
#define _T(string)
wxString m_FrameAddress
void SetReadOnly(bool readOnly)
Set to read only or read write.
DLLIMPORT wxString GetFilterAll()
Generates a simple special filter "All files".
Definition: filefilters.cpp:98
wxString AfterFirst(wxUniChar ch) const
#define wxT(string)
bool IsValid() const
EditorManager * GetEditorManager() const
Definition: manager.cpp:434
wxScintilla * m_pCode
void SetDisassemblyMixedMode(bool mixed)
wxString BeforeFirst(wxUniChar ch, wxString *rest=NULL) const
ProjectManager * GetProjectManager() const
Functions returning pointers to the respective sub-manager instances.
Definition: manager.cpp:429
void OnAdjustLine(wxCommandEvent &event)
DebuggerManager * GetDebuggerManager() const
Definition: manager.cpp:484
void CenterLine(int lineno)
wxString m_FrameFunction
Represents a Code::Blocks project.
Definition: cbproject.h:96
int GetCurrentLine()
Manually declared methods.
wxCheckBox * m_MixedModeCB
bool SetNativeFontInfo(const wxString &info)
virtual const wxString & GetTitle() const
Read the target&#39;s title.
void MarkerDeleteAll(int markerNumber)
Delete all markers with a particular number from all lines.
const wxPoint wxDefaultPosition
void OnMixedModeCB(wxCommandEvent &event)
cbProject * GetActiveProject()
Retrieve the active project.
wxString Read(const wxString &key, const wxString &defaultVal=wxEmptyString)
virtual wxString GetBasePath() const
Read the target&#39;s base path, e.g. if GetFilename() returns "/usr/local/bin/xxx", base path will retur...
const wxString & GetSymbol() const
wxString wxEmptyString
virtual wxString GetPath() const
DLLIMPORT uint64_t cbDebuggerStringToAddress(const wxString &address)
Convert a string in hex form to a uint64_t number.
const wxString & _(const wxString &string)
#define DEBUG_STYLE
#define cbAssert(expr)
Definition: cbexception.h:48
#define wxSCI_STYLE_DEFAULT
Styles in range 32..38 are predefined for parts of the UI and are not used as normal styles...
Definition: wxscintilla.h:163
EditorColourSet * GetColourSet()
wxString GetAddressAsString() const
void Clear(const cbStackFrame &frame)
bool IsEmpty() const
DLLIMPORT void PlaceWindow(wxTopLevelWindow *w, cbPlaceDialogMode mode=pdlBest, bool enforce=false)
Definition: globals.cpp:1177
bool GetLineVisible(int line) const
Is a line visible?
#define DEBUG_MARKER
bool AttachUnknownControl(const wxString &name, wxWindow *control, wxWindow *parent=NULL)
void ClearAll()
Delete all text in the document.
int MarkerAdd(int line, int markerNumber)
Add a marker to a line, returning an ID which can be used to find or delete the marker.
DLLIMPORT bool cbSaveToFile(const wxString &filename, const wxString &contents, wxFontEncoding encoding=wxFONTENCODING_SYSTEM, bool bom=false)
Writes a wxString to a file.
Definition: globals.cpp:721
virtual bool IsRunning() const =0
Is the plugin currently debugging?
void AddAssemblerLine(uint64_t addr, const wxString &line)
int GetLineCount() const
Returns the number of lines in the document. There is always at least one.
DLLIMPORT wxString cbDebuggerAddressToString(uint64_t address)
Convert a uint64_t variable to a hex string that will look like an address.
wxString GetText() const
Retrieve all the text in the document.
int LinesOnScreen() const
Retrieves the number of lines completely visible.
static wxXmlResource * Get()
HighlightLanguage Apply(cbEditor *editor, HighlightLanguage lang, bool colourise)
void SetFirstVisibleLine(int displayLine)
Scroll so that a display line is at the top of the display.
int Printf(const wxString &pszFormat,...)
#define wxSCI_LEX_ASM
Definition: wxscintilla.h:509
virtual void SetValue(bool state)
void GotoLine(int line)
Set caret to start of a line and ensure it is visible.
virtual void RequestUpdate(DebugWindows window)=0
DLLIMPORT int cbMessageBox(const wxString &message, const wxString &caption=wxEmptyString, int style=wxOK, wxWindow *parent=NULL, int x=-1, int y=-1)
wxMessageBox wrapper.
Definition: globals.cpp:1395
HighlightLanguage GetHighlightLanguage(int lexer)
int GetFirstVisibleLine() const
Retrieve the display line at the top of the display.