ScratchABit: action_goto: Update for picotui 1.1.
[ScratchABit.git] / tools / indircalls.py
blobf67dc7c271c2383961292e9b5fab895ed3dd382e
2 # This is a plugin which resolves "indirect jumps/calls to long location"
3 # as present in some RISC architectures. Specifically, for PseudoC sequence
4 # of:
6 # $a0 = value
7 # call $a0
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.
15 import sys
16 import engine
17 import idaapi
20 aspace = engine.ADDRESS_SPACE
22 def inst_in_area(area):
23 addr = area[engine.START]
24 end = area[engine.END] + 1
25 while addr < end:
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()
32 yield inst
33 addr += sz
34 else:
35 addr += 1
38 def main(APP):
39 conv_imm = 0
40 unconv_imm = 0
42 for area in aspace.get_areas():
43 if not "X" in area[engine.PROPS].get("access", ""):
44 continue
45 #print(area[:-2])
46 last_inst = None
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:
50 if not APP.is_ui:
51 print(last_inst)
52 print(i)
53 target_addr = last_inst[2].get_addr()
55 # Change 1
56 if not APP.aspace.is_arg_offset(last_inst.ea, 2):
57 APP.aspace.make_arg_offset(last_inst.ea, 2, target_addr)
58 conv_imm += 1
59 else:
60 unconv_imm += 1
62 # Change 2
63 # Note: side effect of this is that of sequence
64 # $a0 = sym
65 # call $a0
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)
75 last_inst = i
77 engine.analyze(lambda c: print(c))
79 if not APP.is_ui:
80 print("Immediates converted to offsets: %d, already converted: %d" % (conv_imm, unconv_imm))
81 print("Done, press Enter")
82 input()
84 #sys.exit()