Intial commit
This commit is contained in:
61
h8536/analysis.py
Normal file
61
h8536/analysis.py
Normal file
@@ -0,0 +1,61 @@
|
||||
from __future__ import annotations
|
||||
|
||||
from collections.abc import Iterable
|
||||
|
||||
from .decoder import H8536Decoder
|
||||
from .formatting import label_for
|
||||
from .model import Instruction
|
||||
from .tables import FLOW_STOP
|
||||
|
||||
|
||||
def trace(decoder: H8536Decoder, starts: Iterable[int], start_limit: int, end_limit: int) -> dict[int, Instruction]:
|
||||
decoded: dict[int, Instruction] = {}
|
||||
queue = [(addr, decoder.br) for addr in starts if start_limit <= addr < end_limit]
|
||||
seen_starts: set[tuple[int, int | None]] = set()
|
||||
|
||||
while queue:
|
||||
pc, br = queue.pop(0)
|
||||
if (pc, br) in seen_starts:
|
||||
continue
|
||||
seen_starts.add((pc, br))
|
||||
|
||||
while start_limit <= pc < end_limit:
|
||||
decoder.br = br
|
||||
if pc in decoded:
|
||||
break
|
||||
ins = decoder.decode(pc)
|
||||
decoded[pc] = ins
|
||||
next_br = ins.br_value if ins.writes_br else br
|
||||
for target in ins.targets:
|
||||
if start_limit <= target < end_limit and (target, next_br) not in seen_starts:
|
||||
queue.append((target, next_br))
|
||||
if ins.kind in FLOW_STOP or not ins.fallthrough:
|
||||
break
|
||||
pc = (pc + max(ins.size, 1)) & 0xFFFF
|
||||
br = next_br
|
||||
|
||||
return decoded
|
||||
|
||||
|
||||
def linear_sweep(decoder: H8536Decoder, start: int, end: int) -> dict[int, Instruction]:
|
||||
decoded: dict[int, Instruction] = {}
|
||||
pc = start
|
||||
br = decoder.br
|
||||
while pc < end:
|
||||
decoder.br = br
|
||||
ins = decoder.decode(pc)
|
||||
decoded[pc] = ins
|
||||
if ins.writes_br:
|
||||
br = ins.br_value
|
||||
pc += max(ins.size, 1)
|
||||
return decoded
|
||||
|
||||
|
||||
def collect_labels(instructions: Iterable[Instruction], vectors: dict[int, tuple[str, int]]) -> dict[int, str]:
|
||||
labels: dict[int, str] = {}
|
||||
for _vector_addr, (name, target) in vectors.items():
|
||||
labels.setdefault(target, f"vec_{name}_{target:04X}")
|
||||
for ins in instructions:
|
||||
for target in ins.targets:
|
||||
labels.setdefault(target, label_for(target))
|
||||
return labels
|
||||
Reference in New Issue
Block a user