Skip to content

Add objdiff-mcp server + match MSVC function-local statics#1

Open
camden-smallwood wants to merge 2 commits into
HaydnTrigg:mainfrom
camden-smallwood:objdiff-mcp
Open

Add objdiff-mcp server + match MSVC function-local statics#1
camden-smallwood wants to merge 2 commits into
HaydnTrigg:mainfrom
camden-smallwood:objdiff-mcp

Conversation

@camden-smallwood

Copy link
Copy Markdown

Summary

This branch adds two independent changes:

1. objdiff-mcp: MCP server for AI-driven decomp matching

A new workspace crate objdiff-mcp exposing objdiff's diffing over the Model Context Protocol (rmcp 2.1) so a model can drive matching without the UI.

Runs persistently over stdio (--transport stdio) or a shared HTTP instance (--transport http --bind ...). State (loaded project + diff config) is shared across sessions for the life of the process.

Tools:

  • open_project / list_units — load objdiff.json, refer to units by name
  • diff_function — side-by-side per-instruction diff + match% for one function
  • diff_overview — functions ranked worst-match-first
  • build — run the project's build command for a unit (via objdiff-core run_make)
  • set_config — persistent diff/disassembly config overrides
  • version

diff_function / diff_overview accept either a project unit or explicit target/base object paths, plus per-call config overrides.

2. Match MSVC function-local statics by stable function+type tail

MSVC decorates a function-local static as ?<localname>@?<scope>@??<func>@<sig>@4<type>@<access>. The <localname> (the source variable name — e.g. a macro's info vs __info) and the <scope> disambiguator (a compiler-assigned index that shifts with the surrounding function body) are both unstable across recompiles, but the enclosing function, type, and storage class uniquely identify the static.

Relocations to such statics now also match on that stable tail, including section-less external/COMDAT references. Their debug-metadata contents (message text, line number) legitimately vary across recompiles and are still diffed as data separately. Unit tests cover the name/scope stripping and the positive/negative match cases.

New workspace crate `objdiff-mcp` exposing objdiff's diffing over the
Model Context Protocol (rmcp 2.1) so a model can drive matching without UI.

Runs persistently over stdio (--transport stdio) or a shared HTTP instance
(--transport http --bind ...). State (loaded project + diff config) is shared
across sessions for the life of the process.

Tools:
- open_project / list_units: load objdiff.json, refer to units by name
- diff_function: side-by-side per-instruction diff + match% for one function
- diff_overview: functions ranked worst-match-first
- build: run the project's build command for a unit (via objdiff-core run_make)
- set_config: persistent diff/disassembly config overrides
- version

diff_function / diff_overview accept either a project unit or explicit
target/base object paths, plus per-call config overrides.

Added to workspace members (not default-members) to keep default builds lean.
MSVC decorates a function-local static as ?<localname>@?<scope>@??<func>@<sig>@4<type>@<access>.
The local name and scope disambiguator are unstable across recompiles, but the enclosing
function, type and storage class uniquely identify the static. Match relocations to such
statics on that stable tail, including section-less external/COMDAT references.
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