2 # This is a plugin which resolves "indirect jumps/calls to long location"
3 # as present in some RISC architectures. Specifically, for PseudoC sequence
9 # "value" will be marked as being an address, and sequence above will be
10 # marked as having a "call" xref to "value" address.
12 # This plugin was tested only on Xtensa architecture so far, and may need
13 # tweaks for other archs.
20 aspace
= engine
.ADDRESS_SPACE
22 def inst_in_area(area
):
23 addr
= area
[engine
.START
]
24 end
= area
[engine
.END
] + 1
26 fl
= aspace
.get_flags(addr
)
27 if fl
== engine
.ADDRESS_SPACE
.CODE
:
28 inst
= engine
.Instruction(addr
)
29 engine
._processor
.cmd
= inst
30 sz
= engine
._processor
.ana()
31 engine
._processor
.out()
42 for area
in aspace
.get_areas():
43 if not "X" in area
[engine
.PROPS
].get("access", ""):
47 for i
in inst_in_area(area
):
48 if last_inst
and i
.disasm
in ("goto $a0", "call $a0") and last_inst
.disasm
.startswith("$a0 = "):
49 if last_inst
[2].type == idaapi
.o_imm
:
53 target_addr
= last_inst
[2].get_addr()
56 if not APP
.aspace
.is_arg_offset(last_inst
.ea
, 2):
57 APP
.aspace
.make_arg_offset(last_inst
.ea
, 2, target_addr
)
63 # Note: side effect of this is that of sequence
66 # "$a0 = sym" will be marked as having "c" (call) xref to sym,
67 # whereas before this plugin run, the same line had "o" xref.
68 # More formally correct approach would be to make "call $a0"
69 # line to have "c" xref, but this would lead to doubling size of
70 # xref list. So, this entire situation is considered a feature, not
71 # a bug, and indeed what a user wants (and 2 instructions above
72 # can be considered a single compound instruction anyway).
73 idaapi
.ua_add_cref(0, target_addr
, idaapi
.fl_CN
if i
.disasm
[0] == "c" else idaapi
.fl_JN
)
77 engine
.analyze(lambda c
: print(c
))
80 print("Immediates converted to offsets: %d, already converted: %d" % (conv_imm
, unconv_imm
))
81 print("Done, press Enter")