aboutsummaryrefslogtreecommitdiffstats
path: root/.auto/parked/fast_pc_nums.patch
blob: f06bfe194da09e3ae311aa34ed9014750ab756a6 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
diff --git a/server/patch_server.py b/server/patch_server.py
index 6667e12..5e20671 100644
--- a/server/patch_server.py
+++ b/server/patch_server.py
@@ -1900,7 +1900,7 @@ def _idatui_lit_extent(plain, x):
     return (lo, hi)
 
 
-def _idatui_pc_nums(cf, sl):
+def _idatui_pc_nums(cf, sl, plain=None):
     """Every number literal on one pseudocode line, as
     [{x0, x1, ea, opnum, value, nbytes, fmt}].
 
@@ -1912,16 +1912,26 @@ def _idatui_pc_nums(cf, sl):
     import ida_lines
     import idaapi
 
-    plain = ida_lines.tag_remove(sl.line)
+    # ``plain`` is the untagged line; callers that already have it pass it in
+    # rather than making tag_remove run twice over every line of the function.
+    if plain is None:
+        plain = ida_lines.tag_remove(sl.line)
     out = []
     x = 0
+    # One ctree_item_t for the whole line, and no head/tail at all. They are
+    # SWIG allocations in the innermost loop of a scan that probes every
+    # literal-looking character -- and 'a' to 'f' are hex digits, so `a1`, `v6`
+    # and `sub_1F4C0` all qualify and most columns of a line get probed. head
+    # and tail were never read. (Same three costs as decomp_map's sweep.)
+    item = ida_hexrays.ctree_item_t()
+    line = sl.line
+    get_line_item = cf.get_line_item
     while x < len(plain):
         ch = plain[x]
         if ch not in _IDATUI_LIT_CHARS and ch != "'":
             x += 1
             continue
-        head, item, tail = (ida_hexrays.ctree_item_t() for _ in range(3))
-        if not cf.get_line_item(sl.line, x, True, head, item, tail):
+        if not get_line_item(line, x, True, None, item, None):
             x += 1
             continue
         if item.citype != ida_hexrays.VDI_EXPR:
@@ -1997,7 +2007,7 @@ def pc_nums(
     for i in range(len(sv)):
         plain = ida_lines.tag_remove(sv[i].line)
         compact = _idatui_compact(plain)
-        for rec in _idatui_pc_nums(cf, sv[i]):
+        for rec in _idatui_pc_nums(cf, sv[i], plain):
             out.append({
                 "line": i,
                 "x0": _idatui_compact_col(plain, compact, rec["x0"]),