Skip to content

fix(jolt-program): reject compressed and misaligned rows without Rv64C - #2135

Open
quangvdao wants to merge 1 commit into
mainfrom
quang/riscv-profile-encoding
Open

quangvdao wants to merge 1 commit into
mainfrom
quang/riscv-profile-encoding

Conversation

@quangvdao

Copy link
Copy Markdown
Collaborator

Why

decode_instruction checked only the decoded instruction kind against the selected profile. A profile without Rv64C, such as the existing RV64IM_JOLT, therefore still accepted compressed encodings, and 4-byte instructions at addresses that are only 2-byte aligned. The profile did not constrain encoding width or alignment.

What

  • jolt-program, image/decode.rs: when the profile does not contain SourceExtension::Rv64C, decode_instruction rejects a compressed row with ProgramError::IllegalCompressedInstruction { address }. It then rejects an address that is not 4-byte aligned with MalformedImage("instruction address is not 4-byte aligned"). Both checks run before the kind is decoded, so they take precedence over unknown-opcode and illegal-kind errors. Profiles that contain Rv64C, including the default RV64IMAC_JOLT, take the same path as before, with no new alignment check.
  • jolt-program, error.rs: new variant ProgramError::IllegalCompressedInstruction { address: u64 }.
  • jolt-riscv, profile.rs: new exported RV64I profile (Rv64I source extension only, no inline extensions). It replaces four identical test-local RV64I_ONLY constants across expand/metadata.rs, expand/tests.rs and preprocess/bytecode.rs.

Compatibility:

  • ProgramError is not #[non_exhaustive], so downstream code that matches it exhaustively must handle the new variant. No exhaustive match exists in this workspace.
  • Inputs that were previously accepted under a profile without Rv64C may now fail: images containing compressed instructions, and images whose 4-byte instructions sit at 2-byte-aligned addresses (for example after zero halfword padding, which ELF decoding still skips).
  • Valid programs decoded under the default compressed profile decode identically.

Tests

  • image/decode/tests.rs:
    • rv64i_decodes_every_base_instruction decodes one vector for each of the 52 RV64I kinds under RV64I.
    • rv64i_rejects_non_base_instructions_and_unknown_encodings covers M, A, Zicsr, privileged and inline encodings rejected as IllegalSourceInstruction, and an unknown opcode.
    • compressed_rows_are_rejected_before_kind_and_alignment_checks runs under both RV64I and RV64IM_JOLT. It covers a valid c.addi and an invalid word at a 2-byte-aligned address, and checks that RV64IMAC_JOLT still decodes the compressed row.
    • alignment_is_checked_before_kind_only_without_rv64c checks that misaligned addresses are rejected under both non-compressed profiles before an unknown opcode is reported, and that RV64IMAC_JOLT still accepts 2-byte-aligned rows of either width.
  • image/elf.rs: three decode_elf tests cover the same boundary end to end: compressed rejection under RV64I/RV64IM_JOLT, alignment rejection under both, and acceptance under RV64IMAC_JOLT, plus a base instruction decoded under RV64I.
  • jolt-riscv profile.rs: RV64I source legality over SourceInstructionKind::ALL equals the 52 RV64I base kinds plus the existing extensionless pseudo kinds, and its fingerprint differs from every other exported profile.
  • The existing VirtualHostIO empty-operand test is unchanged and passes; the nonzero-rd rejection guards are unchanged.

Verification

On this branch (macOS): cargo fmt --all --check, python3 scripts/check_style_invariants.py --base origin/main, and cargo clippy -p jolt-riscv -p jolt-program -p tracer -p jolt-host --all-targets -- -D warnings (also with --features field-inline, and -p jolt-program --all-features) all succeed. cargo nextest run -p jolt-riscv -p jolt-program --all-features (167 passed), the same with default features (112 passed), and cargo nextest run -p tracer (174 passed) all succeed. No performance numbers are claimed. The added branch runs once per decoded instruction.

decode_instruction checked only the decoded kind against the selected
profile. A profile without Rv64C, such as RV64IM_JOLT, still accepted
compressed encodings and 4-byte instructions at 2-byte-aligned
addresses.

When the profile lacks Rv64C, decode_instruction now rejects compressed
rows with the new ProgramError::IllegalCompressedInstruction and then
rejects addresses that are not 4-byte aligned, both before the kind is
decoded. Profiles that include Rv64C, including the default
RV64IMAC_JOLT, are unchanged.

jolt-riscv gains a named RV64I profile, which replaces four identical
test-local constants in jolt-program and is used by the new decode and
ELF tests.
@github-actions

Copy link
Copy Markdown
Contributor

📏 PR diff

Note

Actual code changed: 27 lines

🟢 +23 added    🔴 −4 removed

Tests, docs, fixtures, and helper scripts excluded.

Category 🟢 Added 🔴 Removed
⌨️ Actual code +23 −4
🧪 Tests +272 −36
📚 Docs +6 0
📦 Fixtures 0 0
🔧 Helper scripts 0 0
Total diff +301 −40

Every changed line is classified once.

This branch has not been deployed

No deployments
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.

1 participant