Convert the wide uninitialized_copy thunk at 0x0000DF10 to clean C++ - #3
Open
HugoDijkstra wants to merge 2 commits into
Open
HugoDijkstra wants to merge 2 commits into
HugoDijkstra wants to merge 2 commits into
Conversation
Retail's body here is a five-byte jmp into __copy_trivial at 0x000179B0 (Ghidra: thunk_FUN_004179b0) -- the linker folded this wchar_t instantiation onto the narrow one and left a stub for the one external caller, basic_string<unsigned short>::reserve, that still reaches it by address. A plain forwarding definition reproduces the stub without hand-writing the jump: __cdecl, three pointers passed straight through with nothing else live across the call, so MSVC 7.1 sibling-call optimizes the whole function into that one jmp. It lands in its own translation unit rather than next to the existing declaration in stlport_wide_string_reserve.cpp, because merely having a body for this function visible anywhere in that TU perturbed reserve()'s own already-matched register allocation for the call. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_017n3PU2fXgkEdmRzrtDmsCU
Retail's body at 0x0000BDA0 turned out to match vendor/stlport/stl/_monetary.h's own base-class do_put(long double) exactly: it ignores the units value and passes an uninitialized 64-byte buffer to the do_put(string) overload through the vtable, confirmed against the real vendored header rather than guessed. The vendored-header instantiation route (stlport_money_put.cpp) gets close but routes free() through the CRT import table, which can't reproduce retail's direct call. A hand-rolled shim lands 174 of 174 bytes with only five load/store displacements differing, fixing three traps already known elsewhere in this codebase: free() needs C++ linkage (not extern "C") for the byte EH-state store; allocator<CharT> needs a user-declared default constructor to avoid a value-init zero-store; and the string temporary's allocator-storage member has to be dropped entirely, not just emptied, or it pads the frame four bytes and shifts every later local. What's left is exactly which stack slot the locale temporary lands in -- retail reuses the dead incoming str-parameter slot, this body gives it a fresh one. Declaration order doesn't move it; next attempt should look at what else is competing for that slot. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_0135fAF2xVRZjiD7q7gF9fUX
Collaborator
Author
|
Added a second commit: banked a 0.95-score partial for money_put::do_put(long double) at 0x0000BDA0 (reverse/attempts/0x0000bda0.cpp, logged in reverse/re_attempts.log). It's byte-count-exact (174/174) with only one stack-slot placement still differing from retail -- documented in the commit message and the stash file for whoever picks it up next. Doesn't change matched-byte progress on its own (it's a partial, not a landed match), but leaves the next attempt much closer than the prior "attempted, no stash" state. |
Contributor
|
Thanks for the PR! I gave you write permissions so you can push to master directly now |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
0x0000DF10(?uninitialized_copy@_STL@@YAPAGPAG00@Z, the widebasic_string<unsigned short>::reservecopy helper) is a five-bytejmpinto__copy_trivialat0x000179B0(Ghidra:thunk_FUN_004179b0) — the linker folded this instantiation onto the narrow one and left a stub for the one external caller that still reaches it by address.__cdecl, three pointers passed straight through) that MSVC 7.1 sibling-call optimizes into that exactjmp.stlport_wide_string_reserve.cpp, because merely having a body for this function visible anywhere in that TU perturbedreserve()'s own already-matched register allocation for the call site.Test plan
./build.sh Code/Libraries/Source/WWVegas/WWLib/stlport_wide_uninitialized_copy.cpp— byte-exact match./build.sh Code/Libraries/Source/WWVegas/WWLib/stlport_wide_string_reserve.cpp— unaffected, still byte-exactpython3 tools/check_csv.py— clean🤖 Generated with Claude Code