Skip to content

Add Rust trait-object devirtualization#6608

Open
historicattle wants to merge 1 commit into
rizinorg:devfrom
historicattle:rust
Open

Add Rust trait-object devirtualization#6608
historicattle wants to merge 1 commit into
rizinorg:devfrom
historicattle:rust

Conversation

@historicattle

@historicattle historicattle commented Jul 7, 2026

Copy link
Copy Markdown
Contributor

Your checklist for this pull request

  • I've read the guidelines for contributing to this repository.
  • I made sure to follow the project's coding style.
  • I've documented every RZ_API function and struct this PR changes.
  • I've added tests that prove my changes are effective (required for changes to RZ_API).
  • I've updated the Rizin book with the relevant information (if needed).
  • I've used AI tools to generate fully or partially these code changes and I'm sure the changes are not copyrighted by somebody else.

Detailed description
This adds Rust trait-object RTTI recovery and devirtualization support.

Rust does not expose traditional style RTTI, instead, trait object vtables are plain structs in read-only data with a fixed header layout (drop, size, align) followed by function pointers. Class and trait metadata exists only in mangled symbol names (e.g. ::method). This PR recovers that metadata and uses it to resolve virtual dispatch.

  • Recovers Rust trait object dispatch targets from demangled impl metadata, vtable layouts, and core::any::Any type_id methods.
  • Tracks IL state in the current function, replay callers up to call sites to seed ABI argument registers, and use discovered vtable pointers to resolve virtual calls. Adds recovered xrefs and comments for trait dispatch and Any downcast/type_id cases.

Test plan
Adds tests in cmd_ac and cmd_avD

Currently a few tests are marked BROKEN since they are waiting on rizinorg/rizin-testbins#305

Closing issues
none

@codecov

codecov Bot commented Jul 7, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 50.10870% with 459 lines in your changes missing coverage. Please review.
✅ Project coverage is 49.95%. Comparing base (9836b05) to head (c41ebb3).

Files with missing lines Patch % Lines
librz/core/devirtualize_rust.c 44.83% 236 Missing and 159 partials ⚠️
librz/arch/rtti_rust.c 68.02% 22 Missing and 41 partials ⚠️
librz/core/cmd/cmd_analysis.c 75.00% 1 Missing ⚠️
Additional details and impacted files
Files with missing lines Coverage Δ
librz/arch/rtti.c 75.00% <100.00%> (+1.15%) ⬆️
librz/core/core_private.h 100.00% <ø> (ø)
librz/include/rz_analysis.h 72.72% <ø> (ø)
librz/core/cmd/cmd_analysis.c 53.10% <75.00%> (+0.03%) ⬆️
librz/arch/rtti_rust.c 68.02% <68.02%> (ø)
librz/core/devirtualize_rust.c 44.83% <44.83%> (ø)

... and 15 files with indirect coverage changes


Continue to review full report in Codecov by Harness.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update 9836b05...c41ebb3. Read the comment docs.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@historicattle

Copy link
Copy Markdown
Contributor Author

Will add more tests to improve coverage

Recover Rust trait-object dispatch targets from demangled impl metadata,
vtable layouts, and core::any::Any type_id methods.

Track IL state in the current function, replay callers up to call sites to
seed ABI argument registers, and use discovered vtable pointers to resolve
virtual calls. Add recovered xrefs and comments for trait dispatch and Any
downcast/type_id cases.
Comment thread librz/arch/rtti_rust.c
Comment on lines +3 to +7

#include "analysis_private.h"

#define RUST_VTABLE_HEADER_SLOTS 3
#define RUST_MAX_TRAIT_METHOD_SLOTS 128

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

if you have resource links (official docs, sources, etc..) for this, please add a comment to it!

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.

RUST_VTABLE_HEADER_SLOTS just refers to drop, size, align entries in the header

RUST_MAX_TRAIT_METHOD_SLOTS is a defensive bound i added, it is not a rust ABI limit.

Im sorry, i will remove this

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

no, i wasnt talking about this.

i was actually talking to just add some references on how the rtti for rust works as a doxygen comment above those lines

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

having a limit is ok

Comment thread librz/arch/rtti_rust.c
Comment on lines +31 to +35
return !strcmp(section->name, ".rodata") ||
!strcmp(section->name, ".rdata") ||
!strcmp(section->name, ".data.rel.ro") ||
!strcmp(section->name, ".data.rel.ro.local") ||
rz_str_endswith(section->name, "__const");

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

does this cover also win binaries?

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.

I havent tested it on PE
I will get back in a bit

@wargio wargio left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

LGTM, but all the tests seems to be for x86. do you have anything for arm64 or riscv ?

@historicattle

historicattle commented Jul 14, 2026

Copy link
Copy Markdown
Contributor Author

No, i have only tested it on my local x86 as of now
I will get back in a bit

Edit:
tested on arm64 (compiled the same test file as in the testbins PR)
The tests fail.

I get ERROR: RzIL: cannot set non-bitvector var with a bitvector

im looking into it

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants