11#include " DisassemblyHelper.h"
22#include " Cutter.h"
3+ #include " rz_types_base.h"
4+
5+ typedef struct mmio_lookup_context
6+ {
7+ QString selected;
8+ RVA mmio_address;
9+ } mmio_lookup_context_t ;
10+
11+ static bool lookup_mmio_addr_cb (void *user, const ut64 key, const void *value)
12+ {
13+ mmio_lookup_context_t *ctx = (mmio_lookup_context_t *)user;
14+ if (ctx->selected == (const char *)value) {
15+ ctx->mmio_address = key;
16+ return false ;
17+ }
18+ return true ;
19+ }
320
421DisassemblyTextBlockUserData::DisassemblyTextBlockUserData (const DisassemblyLine &line)
522 : line { line }
@@ -53,12 +70,59 @@ RVA DisassemblyHelper::readDisassemblyArrow(QTextCursor tc)
5370 return userData->line .arrow ;
5471}
5572
73+ DisassemblyHelper::BracketResult DisassemblyHelper::findBracketRange (const QString &line,
74+ int posInLine)
75+ {
76+ BracketResult res;
77+ int openBracket = line.lastIndexOf (' [' , posInLine);
78+ int closeBracket = line.indexOf (' ]' , posInLine);
79+
80+ if (openBracket != -1 && closeBracket != -1 ) {
81+ bool isInside = true ;
82+ for (int i = openBracket + 1 ; i < posInLine; ++i) {
83+ if (line[i] == ' ]' ) {
84+ isInside = false ;
85+ break ;
86+ }
87+ }
88+ if (isInside) {
89+ for (int i = posInLine; i < closeBracket; ++i) {
90+ if (line[i] == ' [' ) {
91+ isInside = false ;
92+ break ;
93+ }
94+ }
95+ }
96+
97+ if (isInside) {
98+ res.found = true ;
99+ res.start = openBracket;
100+ res.length = (closeBracket - openBracket) + 1 ;
101+ res.content = line.mid (res.start , res.length );
102+ }
103+ }
104+ return res;
105+ }
106+
56107DisassemblyHelper::TargetContext DisassemblyHelper::getContextFromCursor (QTextCursor tc)
57108{
109+ int originalPos = tc.position ();
58110 tc.select (QTextCursor::WordUnderCursor);
111+ QString word = tc.selectedText ();
112+ QString line = tc.block ().text ();
113+ int lineStart = tc.block ().position ();
114+ int posInLine = originalPos - lineStart;
115+
116+ auto bracketRes = findBracketRange (line, posInLine);
117+ if (bracketRes.found ) {
118+ tc.setPosition (lineStart + bracketRes.start );
119+ tc.setPosition (lineStart + bracketRes.start + bracketRes.length , QTextCursor::KeepAnchor);
120+ word = bracketRes.content ;
121+ }
122+
59123 TargetContext ctx;
60- ctx.word = tc. selectedText () ;
61- ctx.line = tc. block (). text () ;
124+ ctx.word = word ;
125+ ctx.line = line ;
62126 ctx.offset = DisassemblyHelper::readDisassemblyOffset (tc);
63127 ctx.arrow = DisassemblyHelper::readDisassemblyArrow (tc);
64128 return ctx;
@@ -73,17 +137,35 @@ DisassemblyHelper::TargetAction DisassemblyHelper::resolveTarget(const TargetCon
73137 if (filter & TargetFilter::XRefComments) {
74138 bool showXRefComments = Core ()->getConfigb (" asm.xrefs" );
75139 if (showXRefComments && isXRefFromComment (ctx.offset , ctx.line )) {
76- res.offset = getXRefFromWord (ctx.offset , ctx.word );
140+ res.value = getXRefFromWord (ctx.offset , ctx.word );
77141 res.type = TargetType::XRefComment;
78142 return res;
79143 }
80144 }
81145
82- if (filter & TargetFilter::Variables) {
146+ if (filter & TargetFilter::VariableValues) {
147+ QString inner = ctx.word ;
148+ if (inner.startsWith (' [' ) && inner.endsWith (' ]' )) {
149+ inner = inner.mid (1 , inner.length () - 2 );
150+ }
151+
152+ if (ctx.offset != RVA_INVALID) {
153+ auto vars = Core ()->getVariables (ctx.offset );
154+ for (auto &var : vars) {
155+ if (var.name == inner) {
156+ res.value = Core ()->math (var.value );
157+ res.type = TargetType::VariableValue;
158+ return res;
159+ }
160+ }
161+ }
162+ }
163+
164+ if (filter & TargetFilter::VariableXrefs) {
83165 XrefDescription xref = Core ()->getFirstXRefForVariable (ctx.word , ctx.offset );
84166 if (!xref.from_str .isEmpty () || !xref.to_str .isEmpty ()) {
85- res.offset = xref.from ;
86- res.type = TargetType::VariableName ;
167+ res.value = xref.from ;
168+ res.type = TargetType::VariableXRef ;
87169 return res;
88170 }
89171 }
@@ -98,10 +180,50 @@ DisassemblyHelper::TargetAction DisassemblyHelper::resolveTarget(const TargetCon
98180 if (filter & TargetFilter::Arrows) {
99181 if (ctx.arrow != RVA_INVALID) {
100182 res.type = TargetType::Arrow;
101- res.offset = ctx.arrow ;
183+ res.value = ctx.arrow ;
102184 return res;
103185 }
104186 }
105187
188+ if (!ctx.word .isEmpty ()) {
189+ if (filter & TargetFilter::Registers) {
190+ const auto reg = Core ()->getRegisterRefValue (ctx.word );
191+ if (!reg.name .isEmpty ()) {
192+ res.type = TargetType::Register;
193+ res.value = Core ()->math (reg.value );
194+ return res;
195+ }
196+ }
197+
198+ if (filter & TargetFilter::MMIO) {
199+ mmio_lookup_context_t mmio_ctx;
200+ mmio_ctx.selected = ctx.word ;
201+ mmio_ctx.mmio_address = RVA_INVALID;
202+ auto core = Core ()->lock ();
203+ RzPlatformTarget *arch_target = core->analysis ->arch_target ;
204+ if (arch_target && arch_target->profile ) {
205+ ht_up_foreach (arch_target->profile ->registers_mmio , lookup_mmio_addr_cb, &mmio_ctx);
206+ }
207+ if (mmio_ctx.mmio_address != RVA_INVALID) {
208+ res.value = mmio_ctx.mmio_address ;
209+ res.type = TargetType::MMIO;
210+ return res;
211+ }
212+ }
213+
214+ if (filter & TargetFilter::Memory) {
215+ QString stripped = ctx.word ;
216+ if (stripped.startsWith (' [' ) && stripped.endsWith (' ]' )) {
217+ stripped = stripped.mid (1 , stripped.length () - 2 );
218+ if (Core ()->isValidInputNumValue (stripped)
219+ || Core ()->isValidInputNumValue (ctx.word )) {
220+ res.value = Core ()->math (ctx.word );
221+ res.type = TargetType::Memory;
222+ return res;
223+ }
224+ }
225+ }
226+ }
227+
106228 return res;
107229}
0 commit comments