Skip to content

Commit 2fb37b8

Browse files
committed
Remove tools.domains and format code
1 parent 8d78b1f commit 2fb37b8

17 files changed

Lines changed: 428 additions & 206 deletions

src/striga/domains/_utils.py

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -7,18 +7,14 @@
77

88
class MemoryBacking(Protocol):
99
@property
10-
def image_base(self) -> int:
11-
...
10+
def image_base(self) -> int: ...
1211

1312
@property
14-
def image_size(self) -> int:
15-
...
13+
def image_size(self) -> int: ...
1614

17-
def in_range(self, va: int) -> bool:
18-
...
15+
def in_range(self, va: int) -> bool: ...
1916

20-
def get_data(self, va: int, size: int) -> bytes:
21-
...
17+
def get_data(self, va: int, size: int) -> bytes: ...
2218

2319

2420
def mask_value(value: int, width: int | None) -> int:
@@ -110,7 +106,9 @@ def eval_icmp(predicate: IntPredicate, lhs: int, rhs: int, width: int | None) ->
110106
return False
111107

112108

113-
def eval_funnel_shift_value(high: int, low: int, amount: int, width: int | None, *, left: bool) -> int:
109+
def eval_funnel_shift_value(
110+
high: int, low: int, amount: int, width: int | None, *, left: bool
111+
) -> int:
114112
if width is None or width <= 0:
115113
return 0
116114
shift = amount % width
@@ -129,4 +127,6 @@ def bytes_for_width(width: int) -> int:
129127

130128

131129
def data_from_backing(backing: MemoryBacking) -> tuple[bytearray, int]:
132-
return bytearray(backing.get_data(backing.image_base, backing.image_size)), backing.image_base
130+
return bytearray(
131+
backing.get_data(backing.image_base, backing.image_size)
132+
), backing.image_base

src/striga/domains/concrete.py

Lines changed: 28 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,9 @@ def unknown(self, text: str, width: int | None) -> ConcreteValue:
3434
del text
3535
return ConcreteValue(0, width)
3636

37-
def binary(self, op: Opcode, lhs: ConcreteValue, rhs: ConcreteValue, width: int | None) -> ConcreteValue:
37+
def binary(
38+
self, op: Opcode, lhs: ConcreteValue, rhs: ConcreteValue, width: int | None
39+
) -> ConcreteValue:
3840
return ConcreteValue(eval_binary(op, lhs.value, rhs.value, width), width)
3941

4042
def icmp(
@@ -76,14 +78,18 @@ def funnel_shift(
7678
left: bool,
7779
) -> ConcreteValue:
7880
return ConcreteValue(
79-
eval_funnel_shift_value(high.value, low.value, amount.value, width, left=left),
81+
eval_funnel_shift_value(
82+
high.value, low.value, amount.value, width, left=left
83+
),
8084
width,
8185
)
8286

8387
def concrete_bool(self, val: ConcreteValue) -> bool | None:
8488
return bool(val.value)
8589

86-
def with_width(self, val: ConcreteValue, width: int | None, *, signed: bool = False) -> ConcreteValue:
90+
def with_width(
91+
self, val: ConcreteValue, width: int | None, *, signed: bool = False
92+
) -> ConcreteValue:
8793
if signed:
8894
return ConcreteValue(sext_value(val.value, val.width, width), width)
8995
return ConcreteValue(mask_value(val.value, width), width)
@@ -102,15 +108,24 @@ def from_backing(cls, backing: MemoryBacking) -> ConcreteMemory:
102108
data, base = data_from_backing(backing)
103109
return cls(data, base)
104110

105-
def read(self, offset: ConcreteValue, width: int, *, insn_addr: int = 0) -> ConcreteValue:
111+
def read(
112+
self, offset: ConcreteValue, width: int, *, insn_addr: int = 0
113+
) -> ConcreteValue:
106114
del insn_addr
107115
byte_width = bytes_for_width(width)
108116
value = 0
109117
for i in range(byte_width):
110118
value |= self._read_byte(offset.value + i) << (i * 8)
111119
return ConcreteValue(mask_value(value, width), width)
112120

113-
def write(self, offset: ConcreteValue, value: ConcreteValue, width: int, *, insn_addr: int = 0) -> None:
121+
def write(
122+
self,
123+
offset: ConcreteValue,
124+
value: ConcreteValue,
125+
width: int,
126+
*,
127+
insn_addr: int = 0,
128+
) -> None:
114129
del insn_addr
115130
byte_width = bytes_for_width(width)
116131
concrete = mask_value(value.value, width)
@@ -135,7 +150,11 @@ def _write_byte(self, address: int, value: int) -> None:
135150

136151

137152
class ConcreteRegisters(RegisterState[ConcreteValue]):
138-
def __init__(self, reg_sizes: dict[str, int], initial: dict[str, int | ConcreteValue] | None = None):
153+
def __init__(
154+
self,
155+
reg_sizes: dict[str, int],
156+
initial: dict[str, int | ConcreteValue] | None = None,
157+
):
139158
self._sizes = reg_sizes
140159
initial = initial or {}
141160
self._regs: dict[str, ConcreteValue] = {}
@@ -150,7 +169,9 @@ def read(self, name: str) -> ConcreteValue:
150169
return self._regs[name]
151170

152171
def write(self, name: str, value: ConcreteValue) -> None:
153-
self._regs[name] = ConcreteValue(mask_value(value.value, self._sizes[name]), self._sizes[name])
172+
self._regs[name] = ConcreteValue(
173+
mask_value(value.value, self._sizes[name]), self._sizes[name]
174+
)
154175

155176
def width(self, name: str) -> int:
156177
return self._sizes[name]

src/striga/domains/counting.py

Lines changed: 39 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -46,23 +46,33 @@ def unknown(self, text: str, width: int | None) -> Counted:
4646
del text
4747
return Counted(0, width, {})
4848

49-
def binary(self, op: Opcode, lhs: Counted, rhs: Counted, width: int | None) -> Counted:
49+
def binary(
50+
self, op: Opcode, lhs: Counted, rhs: Counted, width: int | None
51+
) -> Counted:
5052
concrete = eval_binary(op, lhs.value, rhs.value, width)
5153
return Counted(concrete, width, lhs.merge_ops(rhs, op_name=op.name))
5254

53-
def icmp(self, predicate: IntPredicate, lhs: Counted, rhs: Counted, width: int | None) -> Counted:
55+
def icmp(
56+
self, predicate: IntPredicate, lhs: Counted, rhs: Counted, width: int | None
57+
) -> Counted:
5458
concrete = int(eval_icmp(predicate, lhs.value, rhs.value, width))
55-
return Counted(concrete, 1, lhs.merge_ops(rhs, op_name=f"icmp_{predicate.name}"))
59+
return Counted(
60+
concrete, 1, lhs.merge_ops(rhs, op_name=f"icmp_{predicate.name}")
61+
)
5662

57-
def select(self, cond: Counted, true_val: Counted, false_val: Counted, width: int | None) -> Counted:
63+
def select(
64+
self, cond: Counted, true_val: Counted, false_val: Counted, width: int | None
65+
) -> Counted:
5866
chosen = true_val if cond.value else false_val
5967
return Counted(
6068
mask_value(chosen.value, width),
6169
width,
6270
cond.merge_ops(true_val, false_val, op_name="select"),
6371
)
6472

65-
def cast(self, op: Opcode, val: Counted, from_width: int | None, to_width: int | None) -> Counted:
73+
def cast(
74+
self, op: Opcode, val: Counted, from_width: int | None, to_width: int | None
75+
) -> Counted:
6676
if op == Opcode.SExt:
6777
concrete = sext_value(val.value, from_width, to_width)
6878
else:
@@ -80,13 +90,19 @@ def funnel_shift(
8090
*,
8191
left: bool,
8292
) -> Counted:
83-
concrete = eval_funnel_shift_value(high.value, low.value, amount.value, width, left=left)
84-
return Counted(concrete, width, high.merge_ops(low, amount, op_name="funnel_shift"))
93+
concrete = eval_funnel_shift_value(
94+
high.value, low.value, amount.value, width, left=left
95+
)
96+
return Counted(
97+
concrete, width, high.merge_ops(low, amount, op_name="funnel_shift")
98+
)
8599

86100
def concrete_bool(self, val: Counted) -> bool | None:
87101
return bool(val.value)
88102

89-
def with_width(self, val: Counted, width: int | None, *, signed: bool = False) -> Counted:
103+
def with_width(
104+
self, val: Counted, width: int | None, *, signed: bool = False
105+
) -> Counted:
90106
if signed:
91107
return Counted(sext_value(val.value, val.width, width), width, val.ops)
92108
return Counted(mask_value(val.value, width), width, val.ops)
@@ -107,25 +123,35 @@ def read(self, offset: Counted, width: int, *, insn_addr: int = 0) -> Counted:
107123
return stored
108124
if self.backing is not None:
109125
byte_width = width // 8
110-
if self.backing.in_range(offset.value) and self.backing.in_range(offset.value + byte_width - 1):
126+
if self.backing.in_range(offset.value) and self.backing.in_range(
127+
offset.value + byte_width - 1
128+
):
111129
data = self.backing.get_data(offset.value, byte_width)
112130
return Counted.const(int.from_bytes(data, "little"), width)
113131
return Counted.const(0, width)
114132

115-
def write(self, offset: Counted, value: Counted, width: int, *, insn_addr: int = 0) -> None:
133+
def write(
134+
self, offset: Counted, value: Counted, width: int, *, insn_addr: int = 0
135+
) -> None:
116136
del insn_addr
117137
bytes_for_width(width)
118-
self.store[(offset.value, width)] = Counted(mask_value(value.value, width), width, value.ops)
138+
self.store[(offset.value, width)] = Counted(
139+
mask_value(value.value, width), width, value.ops
140+
)
119141

120142

121143
class CountingRegisters(RegisterState[Counted]):
122-
def __init__(self, reg_sizes: dict[str, int], initial: dict[str, int | Counted] | None = None):
144+
def __init__(
145+
self, reg_sizes: dict[str, int], initial: dict[str, int | Counted] | None = None
146+
):
123147
self._sizes = reg_sizes
124148
initial = initial or {}
125149
self._regs: dict[str, Counted] = {}
126150
for name, size in reg_sizes.items():
127151
value = initial.get(name, 0)
128-
self._regs[name] = value if isinstance(value, Counted) else Counted.const(value, size)
152+
self._regs[name] = (
153+
value if isinstance(value, Counted) else Counted.const(value, size)
154+
)
129155

130156
def read(self, name: str) -> Counted:
131157
return self._regs[name]

src/striga/domains/interval.py

Lines changed: 38 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,9 @@ def unknown(self, text: str, width: int | None) -> Interval:
5959
del text
6060
return Interval.full(width or 64)
6161

62-
def binary(self, op: Opcode, lhs: Interval, rhs: Interval, width: int | None) -> Interval:
62+
def binary(
63+
self, op: Opcode, lhs: Interval, rhs: Interval, width: int | None
64+
) -> Interval:
6365
w = width or max(lhs.width, rhs.width, 64)
6466
if lhs.is_exact and rhs.is_exact:
6567
return Interval.exact(eval_binary(op, lhs.lo, rhs.lo, w), w)
@@ -73,10 +75,14 @@ def binary(self, op: Opcode, lhs: Interval, rhs: Interval, width: int | None) ->
7375
return Interval(0, min((1 << w) - 1, lhs.lo), w)
7476
return Interval.full(w)
7577

76-
def icmp(self, predicate: IntPredicate, lhs: Interval, rhs: Interval, width: int | None) -> Interval:
78+
def icmp(
79+
self, predicate: IntPredicate, lhs: Interval, rhs: Interval, width: int | None
80+
) -> Interval:
7781
del width
7882
if lhs.is_exact and rhs.is_exact:
79-
return Interval.exact(int(eval_icmp(predicate, lhs.lo, rhs.lo, lhs.width)), 1)
83+
return Interval.exact(
84+
int(eval_icmp(predicate, lhs.lo, rhs.lo, lhs.width)), 1
85+
)
8086
name = predicate.name
8187
if name == "EQ" and (lhs.hi < rhs.lo or rhs.hi < lhs.lo):
8288
return Interval.exact(0, 1)
@@ -88,13 +94,19 @@ def icmp(self, predicate: IntPredicate, lhs: Interval, rhs: Interval, width: int
8894
return Interval.exact(0, 1)
8995
return Interval.full(1)
9096

91-
def select(self, cond: Interval, true_val: Interval, false_val: Interval, width: int | None) -> Interval:
97+
def select(
98+
self, cond: Interval, true_val: Interval, false_val: Interval, width: int | None
99+
) -> Interval:
92100
if cond.is_exact:
93101
return true_val if cond.lo else false_val
94102
w = width or max(true_val.width, false_val.width, 64)
95-
return self._bounded(min(true_val.lo, false_val.lo), max(true_val.hi, false_val.hi), w)
103+
return self._bounded(
104+
min(true_val.lo, false_val.lo), max(true_val.hi, false_val.hi), w
105+
)
96106

97-
def cast(self, op: Opcode, val: Interval, from_width: int | None, to_width: int | None) -> Interval:
107+
def cast(
108+
self, op: Opcode, val: Interval, from_width: int | None, to_width: int | None
109+
) -> Interval:
98110
w = to_width or val.width
99111
if val.is_exact:
100112
if op == Opcode.SExt:
@@ -115,7 +127,9 @@ def funnel_shift(
115127
) -> Interval:
116128
w = width or max(high.width, low.width, amount.width, 64)
117129
if high.is_exact and low.is_exact and amount.is_exact:
118-
return Interval.exact(eval_funnel_shift_value(high.lo, low.lo, amount.lo, w, left=left), w)
130+
return Interval.exact(
131+
eval_funnel_shift_value(high.lo, low.lo, amount.lo, w, left=left), w
132+
)
119133
return Interval.full(w)
120134

121135
def concrete_bool(self, val: Interval) -> bool | None:
@@ -127,7 +141,9 @@ def concrete_bool(self, val: Interval) -> bool | None:
127141
return True
128142
return None
129143

130-
def with_width(self, val: Interval, width: int | None, *, signed: bool = False) -> Interval:
144+
def with_width(
145+
self, val: Interval, width: int | None, *, signed: bool = False
146+
) -> Interval:
131147
w = width or val.width
132148
if val.is_exact:
133149
if signed:
@@ -162,26 +178,36 @@ def read(self, offset: Interval, width: int, *, insn_addr: int = 0) -> Interval:
162178
return stored
163179
if self.backing is not None:
164180
byte_width = width // 8
165-
if self.backing.in_range(offset.lo) and self.backing.in_range(offset.lo + byte_width - 1):
181+
if self.backing.in_range(offset.lo) and self.backing.in_range(
182+
offset.lo + byte_width - 1
183+
):
166184
data = self.backing.get_data(offset.lo, byte_width)
167185
return Interval.exact(int.from_bytes(data, "little"), width)
168186
return Interval.full(width)
169187

170-
def write(self, offset: Interval, value: Interval, width: int, *, insn_addr: int = 0) -> None:
188+
def write(
189+
self, offset: Interval, value: Interval, width: int, *, insn_addr: int = 0
190+
) -> None:
171191
del insn_addr
172192
bytes_for_width(width)
173193
if offset.is_exact:
174194
self.store[(offset.lo, width)] = value
175195

176196

177197
class IntervalRegisters(RegisterState[Interval]):
178-
def __init__(self, reg_sizes: dict[str, int], initial: dict[str, int | Interval] | None = None):
198+
def __init__(
199+
self,
200+
reg_sizes: dict[str, int],
201+
initial: dict[str, int | Interval] | None = None,
202+
):
179203
self._sizes = reg_sizes
180204
initial = initial or {}
181205
self._regs: dict[str, Interval] = {}
182206
for name, size in reg_sizes.items():
183207
value = initial.get(name, 0)
184-
self._regs[name] = value if isinstance(value, Interval) else Interval.exact(value, size)
208+
self._regs[name] = (
209+
value if isinstance(value, Interval) else Interval.exact(value, size)
210+
)
185211

186212
def read(self, name: str) -> Interval:
187213
return self._regs[name]

0 commit comments

Comments
 (0)