Skip to content

Add MASM lint mode for advice taint analysis - #1263

Merged
bitwalker merged 9 commits into
nextfrom
issue-1209-masm-lint-frontend
Aug 7, 2026
Merged

Add MASM lint mode for advice taint analysis#1263
bitwalker merged 9 commits into
nextfrom
issue-1209-masm-lint-frontend

Conversation

@huitseeker

Copy link
Copy Markdown
Contributor

This PR lets the MASM frontend build a partial HIR world for lint use. This is part of #1209.

Strict MASM disassembly stops on the first procedure it cannot lift. That blocks advice taint analysis on large MASM projects, including the Miden VM core library. This change adds a lint path that skips procedures the frontend cannot lift yet. It records the procedure path, source span, and reason. It also skips callers that depend on skipped procedures.

This change also adds support for mod.masm module index files, relative calls through declared child modules, source dependency metadata, and exp.u32.

This PR does not wire this into midenc --lint. That should be a follow-up PR, with a clear policy for skipped procedures and partial analysis.

@huitseeker
huitseeker requested a review from bitwalker July 7, 2026 16:01
@huitseeker
huitseeker force-pushed the issue-1209-masm-lint-frontend branch from 1fe2758 to d46ac63 Compare July 7, 2026 16:46
@huitseeker
huitseeker marked this pull request as ready for review July 7, 2026 19:35
@huitseeker
huitseeker requested review from greenhat and mooori July 24, 2026 13:47
@huitseeker
huitseeker force-pushed the issue-1209-masm-lint-frontend branch from d46ac63 to 8839518 Compare July 31, 2026 18:34

@bitwalker bitwalker left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looking good! I found a couple of issues, one of which may require a change in Linker, but fairly trivial for the most part. I can get this merged as soon as those are fixed (or we have a plan for fixing them), and will ship a new release of the compiler very soon (basically once this and possibly a couple of other pending PRs land).

Comment thread frontend/masm/src/lift.rs Outdated
return Some(unsupported);
}
}
Op::While { body, .. } | Op::DoWhile { body, .. } | Op::Repeat { body, .. } => {

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This pre-scan treats Op::DoWhile as liftable, but signature validation reaches the unconditional infer_do_while todo!(), and body lifting contains another todo!(). Valid MASM panics instead of recording this procedure as skipped. We should reject the construct during pre-scan or implement both paths.

We should also inspect the condition block for DoWhile

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed, preflight now rejects the whole do-while procedure.

Comment thread frontend/masm/src/lift.rs
**procedure = stub;
}

linker.link(core::iter::empty(), core::iter::empty())?;

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This final linker pass rejects cyclic call graphs before infer_missing_signatures reaches the new cycle-to-SkippedProcedure handling. A recursive component aborts the entire lint world, including unrelated procedures.

I think we may need to add some support to the linker to allow proceeding in the face of certain errors by collecting them and proceeding with linking anyway (i.e. if we encounter recursion, the linker can obviously resolve the symbol references, even if the resulting call graph cannot be assembled to MAST). In such cases the linker could record the cycle as a deferred error, and proceed with linking anyway. The assembler could then consult the linker for non-fatal errors it gathered, and raise them at that point, while the disassembler could raise diagnostics for those without bailing out of disassembly completely.

The alternative is to detect and stub cyclic SCCs before this, but then we're reimplementing stuff the linker already does for us.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Tracked in 0xMiden/miden-vm#3457.

Comment thread frontend/masm/src/lift.rs
)?,
};

if config.lint {

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Signature validation does not cover lift-only invariants like local index bounds. An out-of-range loc_loadw_le passes here and later escapes through lift_bodies, aborting the whole partial world. We probably need to make lifting transactional per procedure or validate every lifting precondition before declaration.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Tracked in #1304

Comment thread frontend/masm/src/lib.rs Outdated
context: Rc<Context>,
) -> Result<DisassembledWorld> {
let inputs = if let Some(sources) = sources {
let metadata = project::collect_dependency_metadata(project, &context)?;

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This collector loads only dependencies declared directly by the root project. A direct source dependency that calls a transitive source dependency is marked skipped, and that skip propagates into valid root code. This should probably accept a resolved dependency graph/full closure as the existing source-based API does.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed, lint disassembly now takes the parsed sources and resolved dependency graph, then reads metadata from the full dependency closure.

@bitwalker
bitwalker force-pushed the issue-1209-masm-lint-frontend branch from 5d83a3b to e036516 Compare August 7, 2026 02:51

@bitwalker bitwalker left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good, thanks! I've added a few commits to address a couple of minor review findings, rather than do another review cycle just for those, but nothing substantial has changed.

@bitwalker
bitwalker merged commit 18ccaaf into next Aug 7, 2026
21 checks passed
@bitwalker
bitwalker deleted the issue-1209-masm-lint-frontend branch August 7, 2026 03:21
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants