summaryrefslogtreecommitdiff
path: root/pkgs/development/compilers/dotnet/source/vmr-compiler-opt-v8.patch
blob: f1d45e0a01379812b26386715982110d37f442c9 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
diff --git a/src/runtime/src/native/corehost/corehost.cpp b/src/runtime/src/native/corehost/corehost.cpp
index 5edc2fbf5d5..1b3f5b1a23a 100644
--- a/src/runtime/src/native/corehost/corehost.cpp
+++ b/src/runtime/src/native/corehost/corehost.cpp
@@ -40,14 +40,27 @@
 #define EMBED_HASH_LO_PART_UTF8 "74e592c2fa383d4a3960714caef0c4f2"
 #define EMBED_HASH_FULL_UTF8    (EMBED_HASH_HI_PART_UTF8 EMBED_HASH_LO_PART_UTF8) // NUL terminated
 
+// This avoids compiler optimization which cause EMBED_HASH_HI_PART_UTF8 EMBED_HASH_LO_PART_UTF8
+// to be placed adjacent causing them to match EMBED_HASH_FULL_UTF8 when searched for replacing.
+// See https://github.com/dotnet/runtime/issues/109611 for more details.
+static bool compare_memory_nooptimization(volatile const char* a, volatile const char* b, size_t length)
+{
+    for (size_t i = 0; i < length; i++)
+    {
+        if (*a++ != *b++)
+            return false;
+    }
+    return true;
+}
+
 bool is_exe_enabled_for_execution(pal::string_t* app_dll)
 {
     constexpr int EMBED_SZ = sizeof(EMBED_HASH_FULL_UTF8) / sizeof(EMBED_HASH_FULL_UTF8[0]);
     constexpr int EMBED_MAX = (EMBED_SZ > 1025 ? EMBED_SZ : 1025); // 1024 DLL name length, 1 NUL
 
     // Contains the EMBED_HASH_FULL_UTF8 value at compile time or the managed DLL name replaced by "dotnet build".
-    // Must not be 'const' because std::string(&embed[0]) below would bind to a const string ctor plus length
-    // where length is determined at compile time (=64) instead of the actual length of the string at runtime.
+    // Must not be 'const' because strlen below could be determined at compile time (=64) instead of the actual
+    // length of the string at runtime.
     static char embed[EMBED_MAX] = EMBED_HASH_FULL_UTF8;     // series of NULs followed by embed hash string
 
     static const char hi_part[] = EMBED_HASH_HI_PART_UTF8;
@@ -64,10 +77,10 @@ bool is_exe_enabled_for_execution(pal::string_t* app_dll)
     size_t hi_len = (sizeof(hi_part) / sizeof(hi_part[0])) - 1;
     size_t lo_len = (sizeof(lo_part) / sizeof(lo_part[0])) - 1;
 
-    std::string binding(&embed[0]);
-    if ((binding.size() >= (hi_len + lo_len)) &&
-        binding.compare(0, hi_len, &hi_part[0]) == 0 &&
-        binding.compare(hi_len, lo_len, &lo_part[0]) == 0)
+    size_t binding_len = strlen(&embed[0]);
+    if ((binding_len >= (hi_len + lo_len))
+         && compare_memory_nooptimization(&embed[0], hi_part, hi_len) == 0
+         && compare_memory_nooptimization(&embed[hi_len], lo_part, lo_len))
     {
         trace::error(_X("This executable is not bound to a managed DLL to execute. The binding value is: '%s'"), app_dll->c_str());
         return false;