fix(comparison): normalize CFG identity by numeric addresses (#593)

Equivalent hexadecimal addresses no longer collapse a fully observed CFG to unknown, and duplicate numeric block starts are rejected even when spelled differently.
This commit is contained in:
Rudy Mizrahi Celekli authored and GitHub committed 2026-10-06 01:51:59 +08:00
1 parent 9997152c2d
commit d1e5c0e1fd
2 files changed
+67 -18

No files matched your search

+24 -18
View File
@@ -40,30 +40,36 @@ export const functionMatch = (
export const normalizeCfg = (
blocks: FunctionSnapshot["collections"]["basic_blocks"]["items"],
): readonly unknown[] | null => {
const parsed = blocks.map((block) => ({
block,
start: parseAddress(block.start),
end: parseAddress(block.end),
}));
if (parsed.some(({ start, end }) => start === null || end === null))
return null;
const parsed: {
block: (typeof blocks)[number];
start: bigint;
end: bigint;
}[] = [];
for (const block of blocks) {
const start = parseAddress(block.start);
const end = parseAddress(block.end);
if (start === null || end === null || end <= start) return null;
parsed.push({ block, start, end });
}
const ordered = parsed.sort((left, right) =>
(left.start ?? 0n) < (right.start ?? 0n) ? -1 : 1,
left.start < right.start ? -1 : left.start > right.start ? 1 : 0,
);
if (new Set(ordered.map(({ block }) => block.start)).size !== ordered.length)
if (new Set(ordered.map(({ start }) => start)).size !== ordered.length)
return null;
if (ordered.some(({ start, end }) => (end ?? 0n) <= (start ?? 0n)))
return null;
const indices = new Map(
ordered.map(({ block }, index) => [block.start, index]),
);
const indices = new Map(ordered.map(({ start }, index) => [start, index]));
const graph = [];
for (const { block, start, end } of ordered) {
const successors = block.successors.map((address) => indices.get(address));
if (successors.some((index) => index === undefined)) return null;
const successors: number[] = [];
for (const address of block.successors) {
const parsedAddress = parseAddress(address);
if (parsedAddress === null) return null;
const index = indices.get(parsedAddress);
if (index === undefined) return null;
successors.push(index);
}
graph.push({
size: String((end ?? 0n) - (start ?? 0n)),
successors: successors.sort((left, right) => (left ?? 0) - (right ?? 0)),
size: String(end - start),
successors: successors.sort((left, right) => left - right),
});
}
return graph;