[mono] Use unsigned char when computing UTF8 string hashes (#83273)
authorAleksey Kliger (λgeek) <alklig@microsoft.com>
Mon, 13 Mar 2023 14:14:21 +0000 (10:14 -0400)
committerGitHub <noreply@github.com>
Mon, 13 Mar 2023 14:14:21 +0000 (10:14 -0400)
commitd3f7d59e8dc44e5ce22c8ec9c011a1b72d7e9e92
tree6114a41dd5a8c53583f49a4945aca7b77c1c8c4a
parentbbc7e067fba1aa7d0c1bd6ac630340816522f0d3
[mono] Use unsigned char when computing UTF8 string hashes (#83273)

* [mono] Use `unsigned char` when computing UTF8 string hashes

The C standard does not specify whether `char` is signed or unsigned, it is implementation defined.

Apparently Android aarch64 makes a different choice than other platforms (at least macOS arm64 and Windows x64 give different results).

Mono uses `mono_metadata_str_hash` in the AOT compiler and AOT runtime to optimize class name lookup.  As a result, classes whose names include UTF-8 continuation bytes (with the high bit = 1) will hash differently in the AOT compiler and on the device.

Fixes https://github.com/dotnet/runtime/issues/82187
Fixes https://github.com/dotnet/runtime/issues/78638

* [aot] add DEBUG_AOT_NAME_TABLE code for debugging the class names

   AOT compiler: Emits a second "class_name_table_debug" symbol that has all the class names and hashes as strings.

   AOT runtime: warns if a class is not found in the name cache

* Add regression test
src/mono/mono/eglib/ghashtable.c
src/mono/mono/metadata/metadata.c
src/mono/mono/mini/aot-compiler.c
src/mono/mono/mini/aot-runtime.c
src/mono/mono/mini/aot-runtime.h
src/tests/Loader/classloader/regressions/GitHub_82187/GitHub_82187.csproj [new file with mode: 0644]
src/tests/Loader/classloader/regressions/GitHub_82187/repro.cs [new file with mode: 0644]