1+ // This file implements accessibility interface for Disassembly
2+ #ifndef QT_NO_ACCESSIBILITY
3+ #include " AccessibleDisassembly.h"
4+ #include " Disassembly.h"
5+ #include " Bridge.h"
6+
7+ AccessibleDisassembly::AccessibleDisassembly (QWidget* w) : AccessibleAbstractTableView(w)
8+ {
9+ }
10+
11+ AccessibleDisassembly::~AccessibleDisassembly ()
12+ {
13+ }
14+
15+ Disassembly* AccessibleDisassembly::dis () const
16+ {
17+ return dynamic_cast <Disassembly*>(m_tableView);
18+ }
19+
20+ bool AccessibleDisassembly::isRowSelected (int row) const
21+ {
22+ // row includes title
23+ auto dis = this ->dis ();
24+ try
25+ {
26+ return dis->getInitialSelection () == dis->mInstBuffer .at (row - 1 ).rva ;
27+ }
28+ catch (std::out_of_range)
29+ {
30+ return false ;
31+ }
32+ }
33+
34+ // TODO: multi-selection
35+ int AccessibleDisassembly::selectedRowCount () const
36+ {
37+ // row includes title
38+ auto dis = this ->dis ();
39+ const auto & inst = dis->mInstBuffer ;
40+ auto sel = dis->getInitialSelection ();
41+ if (sel >= inst.first ().rva && sel <= inst.back ().rva )
42+ return 1 ;
43+ else
44+ return 0 ;
45+ }
46+
47+ static int findFirstSelection (duint sel, const QList<Instruction_t> & inst)
48+ {
49+ if (sel >= inst.first ().rva && sel <= inst.back ().rva )
50+ {
51+ for (int i = 0 ; i < inst.size (); i++)
52+ {
53+ if (inst[i].rva == sel)
54+ {
55+ return i + 1 ;
56+ }
57+ }
58+ }
59+ return -1 ;
60+ }
61+
62+ QList<int > AccessibleDisassembly::selectedRows () const
63+ {
64+ auto dis = this ->dis ();
65+ int selectedRow = findFirstSelection (dis->getInitialSelection (), dis->mInstBuffer );
66+ if (selectedRow != -1 )
67+ return QList<int >({ selectedRow });
68+ else
69+ return QList<int >();
70+ }
71+
72+ int AccessibleDisassembly::selectedCellCount () const
73+ {
74+ return selectedRowCount ();
75+ }
76+
77+ QList<QAccessibleInterface*> AccessibleDisassembly::selectedCells () const
78+ {
79+ auto dis = this ->dis ();
80+ int selectedRow = findFirstSelection (dis->getInitialSelection (), dis->mInstBuffer );
81+ if (selectedRow != -1 )
82+ return QList<QAccessibleInterface*>({ cellAt (selectedRow, selectedColumns ().first ()) });
83+ else
84+ return QList<QAccessibleInterface*>();
85+ }
86+
87+ static QString getDisassemblyMnemonicBrief (const Instruction_t & inst)
88+ {
89+ char brief[MAX_STRING_SIZE] = " " ;
90+ QString mnem;
91+ for (const ZydisTokenizer::SingleToken & token : inst.tokens .tokens )
92+ {
93+ if (token.type != ZydisTokenizer::TokenType::Space && token.type != ZydisTokenizer::TokenType::Prefix)
94+ {
95+ mnem = token.text ;
96+ break ;
97+ }
98+ }
99+ if (mnem.isEmpty ())
100+ mnem = inst.instStr ;
101+
102+ int index = mnem.indexOf (' ' );
103+ if (index != -1 )
104+ mnem.truncate (index);
105+ DbgFunctions ()->GetMnemonicBrief (mnem.toUtf8 ().constData (), MAX_STRING_SIZE, brief);
106+ return QString::fromUtf8 (brief);
107+ }
108+
109+ QString AccessibleDisassembly::getCellContent (int row, int col) const
110+ {
111+ const Disassembly & d = *dis ();
112+ const Instruction_t & inst = d.mInstBuffer .at (row);
113+ duint cur_addr = d.rvaToVa (inst.rva );
114+ switch (col)
115+ {
116+ case Disassembly::ColAddress:
117+ {
118+ QString label;
119+ return d.getAddrText (cur_addr, label, true );
120+ }
121+ case Disassembly::ColBytes:
122+ {
123+ QString bytes;
124+ RichTextPainter::htmlRichText (d.getRichBytes (inst, false ), nullptr , bytes);
125+ return bytes;
126+ }
127+ case Disassembly::ColDisassembly:
128+ {
129+ QString disassembly;
130+ for (const auto & token : inst.tokens .tokens )
131+ disassembly += token.text ;
132+ return disassembly;
133+ }
134+ case Disassembly::ColMnemonicBrief:
135+ {
136+ RichTextPainter::List richText;
137+ if (d.mShowMnemonicBrief )
138+ return getDisassemblyMnemonicBrief (inst);
139+ else
140+ return QString ();
141+ }
142+ case Disassembly::ColComment:
143+ {
144+ QString comment;
145+ bool autocomment;
146+ GetCommentFormat (cur_addr, comment, &autocomment);
147+ if (autocomment || comment.isEmpty ()) // prefer label over auto-comment
148+ {
149+ char label[MAX_LABEL_SIZE];
150+ if (DbgGetLabelAt (cur_addr, SEG_DEFAULT, label))
151+ {
152+ comment = QString::fromUtf8 (label);
153+ }
154+ }
155+ if (d.mShowMnemonicBrief && d.getColumnHidden (Disassembly::ColMnemonicBrief))
156+ {
157+ comment += ' ' + getDisassemblyMnemonicBrief (inst);
158+ }
159+ return comment;
160+ }
161+ default :
162+ return QString ();
163+ }
164+ }
165+
166+ #endif
0 commit comments