[ASan][Windows] Intercept memcpy when the CRT provides it separately from memmove (#221491)

This is the third retry in a attempt to fix
https://github.com/llvm/llvm-project/issues/126077 (the other two
attempts being https://github.com/llvm/llvm-project/pull/192060 and
https://github.com/llvm/llvm-project/pull/193633)

I was looking at the wrong thing: I was trying to compare `&memcpy` and
`&memmove` in the ASan runtime itself; but the real problem in
https://github.com/llvm/llvm-project/issues/126077 was the dynamic CRT,
which provides non-aliased `&memcpy`.

Please see repro and output:

[output.txt](https://github.com/user-attachments/files/31870348/output.txt)

Historically, the CRT provided `memcpy` and `memmove` as a single
implementation, aliasing both symbols. Since Visual Studio 17.7
(vcruntime140.dll 14.38), [a rewrite of
`memmove`](https://devblogs.microsoft.com/cppblog/msvc-backend-updates-since-visual-studio-2022-version-17-3/)
has changed that. Instead of being aliased, `memcpy` now becomes a thunk
to `memmove`.

We now patch both symbols only if they are distinct (different
addresses). This currently applies only to the dynamic CRT, but if in
the future the static CRT provides two implementations, that should be
covered too.

Assisted by: Claude Fable 5

Fixes #126077

GitOrigin-RevId: 32681decfa6079748836719d9ddf8667fd2b81fc
6 files changed