Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Use the Windows API to demangle MSVC symbols on Windows #257

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
ZivDero wants to merge 4 commits into encounter:main
base: main
Choose a base branch
Loading
from ZivDero:msvc-undname

Conversation

@ZivDero
Copy link

@ZivDero ZivDero commented Sep 8, 2025
edited
Loading

This PR adds support to use the Windows API to demangle MSVC symbols on Windows.
Shouldn't affect other platforms.
Resolves #252

image

ifarbod reacted with thumbs up emoji
Copy link
Owner

Thanks for the PR! While a cool idea in theory, I’d much prefer to try to improve the built-in demangler as much as possible. That way, all platforms benefit (including web / decomp.me).

Copy link
Author

ZivDero commented Sep 8, 2025
edited
Loading

Thanks for the PR! While a cool idea in theory, I’d much prefer to try to improve the built-in demangler as much as possible. That way, all platforms benefit (including web / decomp.me).

While I agree in principle, since MSVC mangling isn't documented, that may prove more challenging.

Here are the test diff for this PR:

────────────┬───────────────────────────────────────────────────────────────────────────────────────────────────────────────
 143 143 │ },
 144 144 │ Symbol {
 145 145 │ name: "?Dot@Vector@@QEAAMPEAU1@@Z",
 146 146 │ demangled_name: Some(
 147 │- "public: float __cdecl Vector::Dot(struct Vector *)",
 147 │+ "public: float __cdecl Vector::Dot(struct Vector * __ptr64) __ptr64",
 148 148 │ ),
 149 149 │ address: 0,
 150 150 │ size: 87,
 151 151 │ kind: Function,
┈┈┈┈┈┈┈┈┈┈┈┈┼┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈
 158 158 │ },
 159 159 │ Symbol {
 160 160 │ name: "?DistSq@Vector@@QEAAMPEAU1@@Z",
 161 161 │ demangled_name: Some(
 162 │- "public: float __cdecl Vector::DistSq(struct Vector *)",
 162 │+ "public: float __cdecl Vector::DistSq(struct Vector * __ptr64) __ptr64",
 163 163 │ ),
 164 164 │ address: 0,
 165 165 │ size: 141,
 166 166 │ kind: Function,
┈┈┈┈┈┈┈┈┈┈┈┈┼┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈
 173 173 │ },
 174 174 │ Symbol {
 175 175 │ name: "?Sub@Vector@@QEAAXPEAU1@0@Z",
 176 176 │ demangled_name: Some(
 177 │- "public: void __cdecl Vector::Sub(struct Vector *, struct Vector *)",
 177 │+ "public: void __cdecl Vector::Sub(struct Vector * __ptr64,struct Vector * __ptr64) __ptr64",
 178 178 │ ),
 179 179 │ address: 0,
 180 180 │ size: 105,
 181 181 │ kind: Function,
┈┈┈┈┈┈┈┈┈┈┈┈┼┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈
 188 188 │ },
 189 189 │ Symbol {
 190 190 │ name: "?Vector_MagSquared@@YAMPEAUVector@@@Z",
 191 191 │ demangled_name: Some(
 192 │- "float __cdecl Vector_MagSquared(struct Vector *)",
 192 │+ "float __cdecl Vector_MagSquared(struct Vector * __ptr64)",
 193 193 │ ),
 194 194 │ address: 0,
 195 195 │ size: 82,
 196 196 │ kind: Function,
┈┈┈┈┈┈┈┈┈┈┈┈┼┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈
 203 203 │ },
 204 204 │ Symbol {
 205 205 │ name: "?Tools_CapsuleTestMagSq@@YA_NPEAUVector@@00M@Z",
 206 206 │ demangled_name: Some(
 207 │- "bool __cdecl Tools_CapsuleTestMagSq(struct Vector *, struct Vector *, struct Vector *, float)",
 207 │+ "bool __cdecl Tools_CapsuleTestMagSq(struct Vector * __ptr64,struct Vector * __ptr64,struct Vector * __ptr64,float)",
 208 208 │ ),
 209 209 │ address: 0,
 210 210 │ size: 429,
 211 211 │ kind: Function,
┈┈┈┈┈┈┈┈┈┈┈┈┼┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈
 574 574 │ },
 575 575 │ Symbol {
 576 576 │ name: "?Tools_CapsuleTestMagSq@@YA_NPEAUVector@@00M@Z$rtcName1ドル",
 577 577 │ demangled_name: Some(
 578 │- "bool __cdecl Tools_CapsuleTestMagSq(struct Vector *, struct Vector *, struct Vector *, float)",
 578 │+ "?Tools_CapsuleTestMagSq@@YA_NPEAUVector@@00M@Z$rtcName1ドル",
 579 579 │ ),
 580 580 │ address: 16,
 581 581 │ size: 12,
 582 582 │ kind: Object,
┈┈┈┈┈┈┈┈┈┈┈┈┼┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈
 589 589 │ },
 590 590 │ Symbol {
 591 591 │ name: "?Tools_CapsuleTestMagSq@@YA_NPEAUVector@@00M@Z$rtcName2ドル",
 592 592 │ demangled_name: Some(
 593 │- "bool __cdecl Tools_CapsuleTestMagSq(struct Vector *, struct Vector *, struct Vector *, float)",
 593 │+ "?Tools_CapsuleTestMagSq@@YA_NPEAUVector@@00M@Z$rtcName2ドル",
 594 594 │ ),
 595 595 │ address: 28,
 596 596 │ size: 20,
 597 597 │ kind: Object,
┈┈┈┈┈┈┈┈┈┈┈┈┼┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈
 604 604 │ },
 605 605 │ Symbol {
 606 606 │ name: "?Tools_CapsuleTestMagSq@@YA_NPEAUVector@@00M@Z$rtcVarDesc",
 607 607 │ demangled_name: Some(
 608 │- "bool __cdecl Tools_CapsuleTestMagSq(struct Vector *, struct Vector *, struct Vector *, float)",
 608 │+ "?Tools_CapsuleTestMagSq@@YA_NPEAUVector@@00M@Z$rtcVarDesc",
 609 609 │ ),
 610 610 │ address: 48,
 611 611 │ size: 192,
 612 612 │ kind: Object,
┈┈┈┈┈┈┈┈┈┈┈┈┼┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈
 619 619 │ },
 620 620 │ Symbol {
 621 621 │ name: "?Tools_CapsuleTestMagSq@@YA_NPEAUVector@@00M@Z$rtcFrameData",
 622 622 │ demangled_name: Some(
 623 │- "bool __cdecl Tools_CapsuleTestMagSq(struct Vector *, struct Vector *, struct Vector *, float)",
 623 │+ "?Tools_CapsuleTestMagSq@@YA_NPEAUVector@@00M@Z$rtcFrameData",
 624 624 │ ),
 625 625 │ address: 240,
 626 626 │ size: 16,
 627 627 │ kind: Object,
────────────┴───────────────────────────────────────────────────────────────────────────────────────────────────────────────

Most of these are alright IMO, though the fact that Microsoft's official API can't unmangle the Tools_CapsuleTestMagSq ones is interesting.

What are your thoughts on this?

Copy link
Owner

The fact that there's already instances where it regresses is unfortunate! And the __ptr64 feels like noise to me.

I just tried out the undname-rs library with

❯ cargo run --example undecorate_name '?_Release@?$_com_ptr_t@V?$_com_IIID@UIPiggyback@@1ドル?IID_IPiggyback@@3U_GUID@@B@@@@AAEXXZ'
private: void __thiscall _com_ptr_t<class _com_IIID<struct IPiggyback, &struct _GUID const IID_IPiggyback>>::_Release(void)

and it seems to work with the COM symbols, which is great! But it chokes on the same symbols that UnDecorateSymbolName does. Those look like they're static variables at a glance?

Copy link
Author

ZivDero commented Sep 8, 2025
edited
Loading

The fact that there's already instances where it regresses is unfortunate! And the __ptr64 feels like noise to me.

I just tried out the undname-rs library with

❯ cargo run --example undecorate_name '?_Release@?$_com_ptr_t@V?$_com_IIID@UIPiggyback@@1ドル?IID_IPiggyback@@3U_GUID@@B@@@@AAEXXZ'
private: void __thiscall _com_ptr_t<class _com_IIID<struct IPiggyback, &struct _GUID const IID_IPiggyback>>::_Release(void)

and it seems to work with the COM symbols, which is great! But it chokes on the same symbols that UnDecorateSymbolName does. Those look like they're static variables at a glance?

(削除) I know for a fact that IDA Pro also fails to unmangle function static variables. Perhaps it's also using the Windows API. (削除ここまで) Scratch that, it does not. What we could do is leave msvc-demangler in place, but then if we're on Windows pass the result to the Windows function, so that it can unmangle anything that the the lib couldn't. That way we don't generate extra diffs and also get the widest coverage.

Copy link
Owner

Sure, having the fallback seems good, but it looks like msvc-demangler is actually ignoring the static variable name, and instead just printing the demangled function itself, which seems like a bug too.

Copy link
Author

ZivDero commented Sep 8, 2025

Sure, having the fallback seems good, but it looks like msvc-demangler is actually ignoring the static variable name, and instead just printing the demangled function itself, which seems like a bug too.

Right, that's a bug then...
http://demangler.com/ also does the same and gives the function name instead.

Your call, I suppose, whether we want to keep this not-quite-right behavior in.
Checked undname.exe that comes with Visual Studio - also does not demangle the data symbol. Notably, this only applies to in-function data, globals are de-mangled fine.

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

Reviewers

No reviews

Assignees

No one assigned

Labels

None yet

Projects

None yet

Milestone

No milestone

Development

Successfully merging this pull request may close these issues.

MSVC name demangler cannot demangle COM ptr mangled names

AltStyle によって変換されたページ (->オリジナル) /