[compiler-rt] [win/asan] Support instructions in GetInstructionSize used by Wine. (PR #113085)
via llvm-commits
llvm-commits at lists.llvm.org
Wed Nov 6 15:21:56 PST 2024
Bernhard =?utf-8?q?Übelacker?= <bernhardu at mailbox.org>,
Bernhard =?utf-8?q?Übelacker?= <bernhardu at mailbox.org>,
Bernhard =?utf-8?q?Übelacker?= <bernhardu at mailbox.org>,
Bernhard =?utf-8?q?Übelacker?= <bernhardu at mailbox.org>
Message-ID:
In-Reply-To: <llvm.org/llvm/llvm-project/pull/113085 at github.com>
https://github.com/bernhardu updated https://github.com/llvm/llvm-project/pull/113085
>From a1b5a083f279800320c34e89894004703f582ec1 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Bernhard=20=C3=9Cbelacker?= <bernhardu at mailbox.org>
Date: Sun, 20 Oct 2024 15:36:19 +0200
Subject: [PATCH 1/5] [win/asan] GetInstructionSize: Fix `8A 05 ...` to return
6 again.
This was already the case before 3bd8f4e,
which probably accidentally inserted
a few new instructions and a return 4 in between.
---
compiler-rt/lib/interception/interception_win.cpp | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/compiler-rt/lib/interception/interception_win.cpp b/compiler-rt/lib/interception/interception_win.cpp
index 077a536dd2a310..3f0acfb3f49df6 100644
--- a/compiler-rt/lib/interception/interception_win.cpp
+++ b/compiler-rt/lib/interception/interception_win.cpp
@@ -634,7 +634,6 @@ static size_t GetInstructionSize(uptr address, size_t* rel_offset = nullptr) {
case 0x018a: // mov al, byte ptr [rcx]
return 2;
- case 0x058A: // 8A 05 XX XX XX XX : mov al, byte ptr [XX XX XX XX]
case 0x7E80: // 80 7E YY XX cmp BYTE PTR [rsi+YY], XX
case 0x7D80: // 80 7D YY XX cmp BYTE PTR [rbp+YY], XX
case 0x7A80: // 80 7A YY XX cmp BYTE PTR [rdx+YY], XX
@@ -643,6 +642,7 @@ static size_t GetInstructionSize(uptr address, size_t* rel_offset = nullptr) {
case 0x7980: // 80 79 YY XX cmp BYTE ptr [rcx+YY], XX
return 4;
+ case 0x058A: // 8A 05 XX XX XX XX : mov al, byte ptr [XX XX XX XX]
case 0x058B: // 8B 05 XX XX XX XX : mov eax, dword ptr [XX XX XX XX]
if (rel_offset)
*rel_offset = 2;
>From d5d6197da6e7f0f2d76dd1fde7f758e1df640de4 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Bernhard=20=C3=9Cbelacker?= <bernhardu at mailbox.org>
Date: Wed, 6 Nov 2024 22:21:14 +0100
Subject: [PATCH 2/5] [win/asan] GetInstructionSize: Make `F6 C1 XX` a generic
entry.
---
compiler-rt/lib/interception/interception_win.cpp | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/compiler-rt/lib/interception/interception_win.cpp b/compiler-rt/lib/interception/interception_win.cpp
index 3f0acfb3f49df6..3fc8c17bcfc360 100644
--- a/compiler-rt/lib/interception/interception_win.cpp
+++ b/compiler-rt/lib/interception/interception_win.cpp
@@ -568,6 +568,9 @@ static size_t GetInstructionSize(uptr address, size_t* rel_offset = nullptr) {
case 0xD284: // 84 D2 : test dl,dl
return 2;
+ case 0xC1F6: // F6 C1 XX : test cl, XX
+ return 3;
+
// Cannot overwrite control-instruction. Return 0 to indicate failure.
case 0x25FF: // FF 25 XX XX XX XX : jmp [XXXXXXXX]
return 0;
@@ -658,7 +661,6 @@ static size_t GetInstructionSize(uptr address, size_t* rel_offset = nullptr) {
}
switch (0x00FFFFFF & *(u32*)address) {
- case 0x07c1f6: // f6 c1 07 : test cl, 0x7
case 0x10b70f: // 0f b7 10 : movzx edx, WORD PTR [rax]
case 0xc00b4d: // 4d 0b c0 : or r8, r8
case 0xc03345: // 45 33 c0 : xor r8d, r8d
>From eade3646405d2bb552a13b8b5540c72652aac3e2 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Bernhard=20=C3=9Cbelacker?= <bernhardu at mailbox.org>
Date: Wed, 6 Nov 2024 22:29:46 +0100
Subject: [PATCH 3/5] [win/asan] GetInstructionSize: Make `83 EC XX` a generic
entry.
---
compiler-rt/lib/interception/interception_win.cpp | 4 +---
1 file changed, 1 insertion(+), 3 deletions(-)
diff --git a/compiler-rt/lib/interception/interception_win.cpp b/compiler-rt/lib/interception/interception_win.cpp
index 3fc8c17bcfc360..83e55f5523ee03 100644
--- a/compiler-rt/lib/interception/interception_win.cpp
+++ b/compiler-rt/lib/interception/interception_win.cpp
@@ -568,6 +568,7 @@ static size_t GetInstructionSize(uptr address, size_t* rel_offset = nullptr) {
case 0xD284: // 84 D2 : test dl,dl
return 2;
+ case 0xEC83: // 83 EC XX : sub esp, XX
case 0xC1F6: // F6 C1 XX : test cl, XX
return 3;
@@ -578,8 +579,6 @@ static size_t GetInstructionSize(uptr address, size_t* rel_offset = nullptr) {
switch (0x00FFFFFF & *(u32*)address) {
case 0xF8E483: // 83 E4 F8 : and esp, 0xFFFFFFF8
- case 0x64EC83: // 83 EC 64 : sub esp, 64h
- return 3;
case 0x24A48D: // 8D A4 24 XX XX XX XX : lea esp, [esp + XX XX XX XX]
return 7;
}
@@ -800,7 +799,6 @@ static size_t GetInstructionSize(uptr address, size_t* rel_offset = nullptr) {
case 0x5D8B: // 8B 5D XX : mov ebx, dword ptr [ebp + XX]
case 0x7D8B: // 8B 7D XX : mov edi, dword ptr [ebp + XX]
case 0x758B: // 8B 75 XX : mov esi, dword ptr [ebp + XX]
- case 0xEC83: // 83 EC XX : sub esp, XX
case 0x75FF: // FF 75 XX : push dword ptr [ebp + XX]
return 3;
case 0xC1F7: // F7 C1 XX YY ZZ WW : test ecx, WWZZYYXX
>From cb5162a17b7514a5447253593651eff57cac784b Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Bernhard=20=C3=9Cbelacker?= <bernhardu at mailbox.org>
Date: Wed, 6 Nov 2024 23:03:52 +0100
Subject: [PATCH 4/5] [win/asan] GetInstructionSize: Make `83 E4 XX` a generic
entry.
---
compiler-rt/lib/interception/interception_win.cpp | 3 +--
1 file changed, 1 insertion(+), 2 deletions(-)
diff --git a/compiler-rt/lib/interception/interception_win.cpp b/compiler-rt/lib/interception/interception_win.cpp
index 83e55f5523ee03..9bea3322927a20 100644
--- a/compiler-rt/lib/interception/interception_win.cpp
+++ b/compiler-rt/lib/interception/interception_win.cpp
@@ -568,6 +568,7 @@ static size_t GetInstructionSize(uptr address, size_t* rel_offset = nullptr) {
case 0xD284: // 84 D2 : test dl,dl
return 2;
+ case 0xE483: // 83 E4 XX : and esp, XX
case 0xEC83: // 83 EC XX : sub esp, XX
case 0xC1F6: // F6 C1 XX : test cl, XX
return 3;
@@ -578,7 +579,6 @@ static size_t GetInstructionSize(uptr address, size_t* rel_offset = nullptr) {
}
switch (0x00FFFFFF & *(u32*)address) {
- case 0xF8E483: // 83 E4 F8 : and esp, 0xFFFFFFF8
case 0x24A48D: // 8D A4 24 XX XX XX XX : lea esp, [esp + XX XX XX XX]
return 7;
}
@@ -707,7 +707,6 @@ static size_t GetInstructionSize(uptr address, size_t* rel_offset = nullptr) {
case 0xdb8548: // 48 85 db : test rbx, rbx
case 0xdb854d: // 4d 85 db : test r11, r11
case 0xdc8b4c: // 4c 8b dc : mov r11, rsp
- case 0xe0e483: // 83 e4 e0 : and esp, 0xFFFFFFE0
case 0xe48548: // 48 85 e4 : test rsp, rsp
case 0xe4854d: // 4d 85 e4 : test r12, r12
case 0xe58948: // 48 89 e5 : mov rbp, rsp
>From 45dccde09832687d1285506ecf5b6b7b293cc188 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Bernhard=20=C3=9Cbelacker?= <bernhardu at mailbox.org>
Date: Wed, 6 Nov 2024 22:58:53 +0100
Subject: [PATCH 5/5] [win/asan] GetInstructionSize: Support instructions used
by Wine binaries.
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
This patch adds several instructions seen when trying to run a
executable built with ASan with llvm-mingw.
(x86 and x86_64, using the git tip in llvm-project).
Adds another missing instruction visible in the issue 96270.
Also includes instructions collected by
Roman Pišl and Eric Pouech in the Wine bug reports below.
Fixes: https://github.com/llvm/llvm-project/issues/96270
Co-authored-by: Roman Pišl <rpisl at seznam.cz>
https://bugs.winehq.org/show_bug.cgi?id=50993
https://bugs.winehq.org/attachment.cgi?id=70233
Co-authored-by: Eric Pouech <eric.pouech at gmail.com>
https://bugs.winehq.org/show_bug.cgi?id=52386
https://bugs.winehq.org/attachment.cgi?id=71626
---
.../lib/interception/interception_win.cpp | 69 +++++++++++++++++++
1 file changed, 69 insertions(+)
diff --git a/compiler-rt/lib/interception/interception_win.cpp b/compiler-rt/lib/interception/interception_win.cpp
index 9bea3322927a20..d03ba03a18651e 100644
--- a/compiler-rt/lib/interception/interception_win.cpp
+++ b/compiler-rt/lib/interception/interception_win.cpp
@@ -528,6 +528,7 @@ static size_t GetInstructionSize(uptr address, size_t* rel_offset = nullptr) {
case 0xb8: // b8 XX XX XX XX : mov eax, XX XX XX XX
case 0xB9: // b9 XX XX XX XX : mov ecx, XX XX XX XX
+ case 0xBA: // ba XX XX XX XX : mov edx, XX XX XX XX
return 5;
// Cannot overwrite control-instruction. Return 0 to indicate failure.
@@ -558,27 +559,41 @@ static size_t GetInstructionSize(uptr address, size_t* rel_offset = nullptr) {
case 0xFF8B: // 8B FF : mov edi, edi
case 0xEC8B: // 8B EC : mov ebp, esp
case 0xc889: // 89 C8 : mov eax, ecx
+ case 0xD189: // 89 D1 : mov ecx, edx
case 0xE589: // 89 E5 : mov ebp, esp
case 0xC18B: // 8B C1 : mov eax, ecx
+ case 0xC031: // 31 C0 : xor eax, eax
+ case 0xC931: // 31 C9 : xor ecx, ecx
+ case 0xD231: // 31 D2 : xor edx, edx
case 0xC033: // 33 C0 : xor eax, eax
case 0xC933: // 33 C9 : xor ecx, ecx
case 0xD233: // 33 D2 : xor edx, edx
case 0xDB84: // 84 DB : test bl,bl
+ case 0xC084: // 84 C0 : test al,al
case 0xC984: // 84 C9 : test cl,cl
case 0xD284: // 84 D2 : test dl,dl
return 2;
+ case 0x3980: // 80 39 XX : cmp BYTE PTR [rcx], XX
case 0xE483: // 83 E4 XX : and esp, XX
case 0xEC83: // 83 EC XX : sub esp, XX
+ case 0x4D8B: // 8B 4D XX : mov XX(%ebp), ecx
+ case 0x558B: // 8B 55 XX : mov XX(%ebp), edx
+ case 0x758B: // 8B 75 XX : mov XX(%ebp), esp
case 0xC1F6: // F6 C1 XX : test cl, XX
return 3;
+ case 0xEC81: // 81 EC XX XX XX XX : sub esp, XX XX XX XX
+ return 6;
+
// Cannot overwrite control-instruction. Return 0 to indicate failure.
case 0x25FF: // FF 25 XX XX XX XX : jmp [XXXXXXXX]
return 0;
}
switch (0x00FFFFFF & *(u32*)address) {
+ case 0x244C8D: // 8D 4C 24 XX : lea ecx, [esp + XX]
+ return 4;
case 0x24A48D: // 8D A4 24 XX XX XX XX : lea esp, [esp + XX XX XX XX]
return 7;
}
@@ -644,6 +659,7 @@ static size_t GetInstructionSize(uptr address, size_t* rel_offset = nullptr) {
case 0x7980: // 80 79 YY XX cmp BYTE ptr [rcx+YY], XX
return 4;
+ case 0xB841: // 41 B8 XX XX XX XX : mov r8d, XX XX XX XX
case 0x058A: // 8A 05 XX XX XX XX : mov al, byte ptr [XX XX XX XX]
case 0x058B: // 8B 05 XX XX XX XX : mov eax, dword ptr [XX XX XX XX]
if (rel_offset)
@@ -674,6 +690,9 @@ static size_t GetInstructionSize(uptr address, size_t* rel_offset = nullptr) {
case 0xc1ff48: // 48 ff c1 : inc rcx
case 0xc1ff49: // 49 ff c1 : inc r9
case 0xc28b41: // 41 8b c2 : mov eax, r10d
+ case 0x01b60f: // 0f b6 01 : movzx eax, BYTE PTR [rcx]
+ case 0x09b60f: // 0f b6 09 : movzx ecx, BYTE PTR [rcx]
+ case 0x11b60f: // 0f b6 11 : movzx edx, BYTE PTR [rcx]
case 0xc2b60f: // 0f b6 c2 : movzx eax, dl
case 0xc2ff48: // 48 ff c2 : inc rdx
case 0xc2ff49: // 49 ff c2 : inc r10
@@ -692,6 +711,7 @@ static size_t GetInstructionSize(uptr address, size_t* rel_offset = nullptr) {
case 0xc98548: // 48 85 c9 : test rcx, rcx
case 0xc9854d: // 4d 85 c9 : test r9, r9
case 0xc98b4c: // 4c 8b c9 : mov r9, rcx
+ case 0xd12948: // 48 29 d1 : sub rcx, rdx
case 0xca2b48: // 48 2b ca : sub rcx, rdx
case 0xca3b48: // 48 3b ca : cmp rcx, rdx
case 0xd12b48: // 48 2b d1 : sub rdx, rcx
@@ -701,16 +721,33 @@ static size_t GetInstructionSize(uptr address, size_t* rel_offset = nullptr) {
case 0xd2854d: // 4d 85 d2 : test r10, r10
case 0xd28b4c: // 4c 8b d2 : mov r10, rdx
case 0xd2b60f: // 0f b6 d2 : movzx edx, dl
+ case 0xd2be0f: // 0f be d2 : movsx edx, dl
case 0xd98b4c: // 4c 8b d9 : mov r11, rcx
case 0xd9f748: // 48 f7 d9 : neg rcx
+ case 0xc03145: // 45 31 c0 : xor r8d,r8d
+ case 0xc93145: // 45 31 c9 : xor r9d,r9d
case 0xdb3345: // 45 33 db : xor r11d, r11d
+ case 0xc08445: // 45 84 c0 : test r8b,r8b
+ case 0xd28445: // 45 84 d2 : test r10b,r10b
case 0xdb8548: // 48 85 db : test rbx, rbx
case 0xdb854d: // 4d 85 db : test r11, r11
case 0xdc8b4c: // 4c 8b dc : mov r11, rsp
case 0xe48548: // 48 85 e4 : test rsp, rsp
case 0xe4854d: // 4d 85 e4 : test r12, r12
+ case 0xc88948: // 48 89 c8 : mov rax,rcx
+ case 0xcb8948: // 48 89 cb : mov rbx,rcx
+ case 0xd08948: // 48 89 d0 : mov rax,rdx
+ case 0xd18948: // 48 89 d1 : mov rcx,rdx
+ case 0xd38948: // 48 89 d3 : mov rbx,rdx
case 0xe58948: // 48 89 e5 : mov rbp, rsp
case 0xed8548: // 48 85 ed : test rbp, rbp
+ case 0xc88949: // 49 89 c8 : mov r8, rcx
+ case 0xc98949: // 49 89 c9 : mov r9, rcx
+ case 0xca8949: // 49 89 ca : mov r10,rcx
+ case 0xd08949: // 49 89 d0 : mov r8, rdx
+ case 0xd18949: // 49 89 d1 : mov r9, rdx
+ case 0xd28949: // 49 89 d2 : mov r10, rdx
+ case 0xd38949: // 49 89 d3 : mov r11, rdx
case 0xed854d: // 4d 85 ed : test r13, r13
case 0xf6854d: // 4d 85 f6 : test r14, r14
case 0xff854d: // 4d 85 ff : test r15, r15
@@ -721,6 +758,8 @@ static size_t GetInstructionSize(uptr address, size_t* rel_offset = nullptr) {
case 0x588948: // 48 89 58 XX : mov QWORD PTR[rax + XX], rbx
case 0xec8348: // 48 83 ec XX : sub rsp, XX
case 0xf88349: // 49 83 f8 XX : cmp r8, XX
+ case 0x148d4e: // 4e 8d 14 XX : lea r10, [rcx+r8*XX]
+ case 0x398366: // 66 83 39 XX : cmp WORD PTR [rcx], XX
return 4;
case 0x246483: // 83 64 24 XX YY : and DWORD PTR [rsp+XX], YY
@@ -735,6 +774,7 @@ static size_t GetInstructionSize(uptr address, size_t* rel_offset = nullptr) {
return 6;
case 0xec8148: // 48 81 EC XX XX XX XX : sub rsp, XXXXXXXX
+ case 0xc0c748: // 48 C7 C0 XX XX XX XX : mov rax, XX XX XX XX
return 7;
// clang-format off
@@ -768,7 +808,13 @@ static size_t GetInstructionSize(uptr address, size_t* rel_offset = nullptr) {
}
switch (*(u32*)(address)) {
+ case 0x01b60f44: // 44 0f b6 01 : movzx r8d, BYTE PTR [rcx]
+ case 0x09b60f44: // 44 0f b6 09 : movzx r9d, BYTE PTR [rcx]
+ case 0x0ab60f44: // 44 0f b6 0a : movzx r8d, BYTE PTR [rdx]
+ case 0x11b60f44: // 44 0f b6 11 : movzx r10d, BYTE PTR [rcx]
case 0x1ab60f44: // 44 0f b6 1a : movzx r11d, BYTE PTR [rdx]
+ case 0x11048d4c: // 4c 8d 04 11 : lea r8,[rcx+rdx*1]
+ case 0xff488d49: // 49 8d 48 ff : lea rcx,[r8-0x1]
return 4;
case 0x24448b48: // 48 8b 44 24 XX : mov rax, QWORD ptr [rsp + XX]
case 0x246c8948: // 48 89 6C 24 XX : mov QWORD ptr [rsp + XX], rbp
@@ -785,6 +831,29 @@ static size_t GetInstructionSize(uptr address, size_t* rel_offset = nullptr) {
return 5;
case 0x24648348: // 48 83 64 24 XX YY : and QWORD PTR [rsp + XX], YY
return 6;
+ case 0x24A48D48: // 48 8D A4 24 XX YY ZZ WW : lea rsp, [rsp + WWZZYYXX]
+ return 8;
+ }
+
+ switch (0xFFFFFFFFFFULL & *(u64*)(address)) {
+ case 0xC07E0F4866: // 66 48 0F 7E C0 : movq rax,xmm0 (for wine fexp)
+ case 0x0000441F0F: // 0F 1F 44 00 00 : nop DWORD PTR [rax+rax*1+0x0]
+ return 5;
+ }
+
+ switch (0xFFFFFFFFFFFFULL & *(u64*)(address)) {
+ case 0x841f0f2e6666: // 66 66 2e 0f 1f 84 YY XX XX XX XX
+ // data16 cs nop WORD PTR [rax+rax*1 + XX XX XX XX]
+ return 11;
+ }
+
+ switch (*(u64*)(address)) {
+ case 0x010101010101b848: // 48 b8 01 01 01 01 01 01 01 01
+ // movabs rax,0x101010101010101
+ return 10;
+ case 0x841f0f2e66666666: // 66 66 66 66 2e 0f 1f 84 YY XX XX XX XX
+ // data16 data16 data16 cs nop WORD PTR [rax+rax*1 + XX XX XX XX]
+ return 13;
}
#else
More information about the llvm-commits
mailing list