Skip to content

Commit 2665318

Browse files
committed
[win/asan] Support in GetInstructionSize instructions used by Wine.
This patch adds several instructions seen when trying to run a executable built with ASan with llvm-mingw, with the tip of the main branch from llvm-project (x86 and x86_64). Also 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. Also changes "44 0f b6 1a" to return 4 instead of 5 (MR 111638). Fixes: #96270 Co-authored-by: Roman Pišl <[email protected]> https://bugs.winehq.org/show_bug.cgi?id=50993 https://bugs.winehq.org/attachment.cgi?id=70233 Co-authored-by: Eric Pouech <[email protected]> https://bugs.winehq.org/show_bug.cgi?id=52386 https://bugs.winehq.org/attachment.cgi?id=71626
1 parent 7b9f988 commit 2665318

File tree

1 file changed

+73
-0
lines changed

1 file changed

+73
-0
lines changed

compiler-rt/lib/interception/interception_win.cpp

Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -528,6 +528,7 @@ static size_t GetInstructionSize(uptr address, size_t* rel_offset = nullptr) {
528528

529529
case 0xb8: // b8 XX XX XX XX : mov eax, XX XX XX XX
530530
case 0xB9: // b9 XX XX XX XX : mov ecx, XX XX XX XX
531+
case 0xBA: // ba XX XX XX XX : mov edx, XX XX XX XX
531532
return 5;
532533

533534
// Cannot overwrite control-instruction. Return 0 to indicate failure.
@@ -558,16 +559,31 @@ static size_t GetInstructionSize(uptr address, size_t* rel_offset = nullptr) {
558559
case 0xFF8B: // 8B FF : mov edi, edi
559560
case 0xEC8B: // 8B EC : mov ebp, esp
560561
case 0xc889: // 89 C8 : mov eax, ecx
562+
case 0xD189: // 89 D1 : mov ecx, edx
561563
case 0xE589: // 89 E5 : mov ebp, esp
562564
case 0xC18B: // 8B C1 : mov eax, ecx
565+
case 0xC031: // 31 C0 : xor eax, eax
566+
case 0xC931: // 31 C9 : xor ecx, ecx
567+
case 0xD231: // 31 D2 : xor edx, edx
563568
case 0xC033: // 33 C0 : xor eax, eax
564569
case 0xC933: // 33 C9 : xor ecx, ecx
565570
case 0xD233: // 33 D2 : xor edx, edx
566571
case 0xDB84: // 84 DB : test bl,bl
572+
case 0xC084: // 84 C0 : test al,al
567573
case 0xC984: // 84 C9 : test cl,cl
568574
case 0xD284: // 84 D2 : test dl,dl
569575
return 2;
570576

577+
case 0x3980: // 80 39 XX : cmp BYTE PTR [rcx], XX
578+
case 0xE483: // 83 E4 XX : and esp, XX
579+
case 0x4D8B: // 8B 4D XX : mov XX(%ebp), ecx
580+
case 0x558B: // 8B 55 XX : mov XX(%ebp), edx
581+
case 0x758B: // 8B 75 XX : mov XX(%ebp), esp
582+
return 3;
583+
584+
case 0xec81: // 81 ec XX XX XX XX : sub esp, XX XX XX XX
585+
return 6;
586+
571587
// Cannot overwrite control-instruction. Return 0 to indicate failure.
572588
case 0x25FF: // FF 25 XX XX XX XX : jmp [XXXXXXXX]
573589
return 0;
@@ -577,6 +593,8 @@ static size_t GetInstructionSize(uptr address, size_t* rel_offset = nullptr) {
577593
case 0xF8E483: // 83 E4 F8 : and esp, 0xFFFFFFF8
578594
case 0x64EC83: // 83 EC 64 : sub esp, 64h
579595
return 3;
596+
case 0x244C8D: // 8D 4C 24 XX : lea ecx, [esp + XX]
597+
return 4;
580598
case 0x24A48D: // 8D A4 24 XX XX XX XX : lea esp, [esp + XX XX XX XX]
581599
return 7;
582600
}
@@ -643,6 +661,8 @@ static size_t GetInstructionSize(uptr address, size_t* rel_offset = nullptr) {
643661
case 0x7980: // 80 79 YY XX cmp BYTE ptr [rcx+YY], XX
644662
return 4;
645663

664+
case 0xb841: // 41 b8 XX XX XX XX : mov r8d, XX XX XX XX
665+
return 6;
646666
case 0x058B: // 8B 05 XX XX XX XX : mov eax, dword ptr [XX XX XX XX]
647667
if (rel_offset)
648668
*rel_offset = 2;
@@ -673,6 +693,9 @@ static size_t GetInstructionSize(uptr address, size_t* rel_offset = nullptr) {
673693
case 0xc1ff48: // 48 ff c1 : inc rcx
674694
case 0xc1ff49: // 49 ff c1 : inc r9
675695
case 0xc28b41: // 41 8b c2 : mov eax, r10d
696+
case 0x01b60f: // 0f b6 01 : movzx eax, BYTE PTR [rcx]
697+
case 0x09b60f: // 0f b6 09 : movzx ecx, BYTE PTR [rcx]
698+
case 0x11b60f: // 0f b6 11 : movzx edx, BYTE PTR [rcx]
676699
case 0xc2b60f: // 0f b6 c2 : movzx eax, dl
677700
case 0xc2ff48: // 48 ff c2 : inc rdx
678701
case 0xc2ff49: // 49 ff c2 : inc r10
@@ -691,6 +714,7 @@ static size_t GetInstructionSize(uptr address, size_t* rel_offset = nullptr) {
691714
case 0xc98548: // 48 85 c9 : test rcx, rcx
692715
case 0xc9854d: // 4d 85 c9 : test r9, r9
693716
case 0xc98b4c: // 4c 8b c9 : mov r9, rcx
717+
case 0xd12948: // 48 29 d1 : sub rcx, rdx
694718
case 0xca2b48: // 48 2b ca : sub rcx, rdx
695719
case 0xca3b48: // 48 3b ca : cmp rcx, rdx
696720
case 0xd12b48: // 48 2b d1 : sub rdx, rcx
@@ -700,17 +724,34 @@ static size_t GetInstructionSize(uptr address, size_t* rel_offset = nullptr) {
700724
case 0xd2854d: // 4d 85 d2 : test r10, r10
701725
case 0xd28b4c: // 4c 8b d2 : mov r10, rdx
702726
case 0xd2b60f: // 0f b6 d2 : movzx edx, dl
727+
case 0xd2be0f: // 0f be d2 : movsx edx, dl
703728
case 0xd98b4c: // 4c 8b d9 : mov r11, rcx
704729
case 0xd9f748: // 48 f7 d9 : neg rcx
730+
case 0xc03145: // 45 31 c0 : xor r8d,r8d
731+
case 0xc93145: // 45 31 c9 : xor r9d,r9d
705732
case 0xdb3345: // 45 33 db : xor r11d, r11d
733+
case 0xc08445: // 45 84 c0 : test r8b,r8b
734+
case 0xd28445: // 45 84 d2 : test r10b,r10b
706735
case 0xdb8548: // 48 85 db : test rbx, rbx
707736
case 0xdb854d: // 4d 85 db : test r11, r11
708737
case 0xdc8b4c: // 4c 8b dc : mov r11, rsp
709738
case 0xe0e483: // 83 e4 e0 : and esp, 0xFFFFFFE0
710739
case 0xe48548: // 48 85 e4 : test rsp, rsp
711740
case 0xe4854d: // 4d 85 e4 : test r12, r12
741+
case 0xc88948: // 48 89 c8 : mov rax,rcx
742+
case 0xcb8948: // 48 89 cb : mov rbx,rcx
743+
case 0xd08948: // 48 89 d0 : mov rax,rdx
744+
case 0xd18948: // 48 89 d1 : mov rcx,rdx
745+
case 0xd38948: // 48 89 d3 : mov rbx,rdx
712746
case 0xe58948: // 48 89 e5 : mov rbp, rsp
713747
case 0xed8548: // 48 85 ed : test rbp, rbp
748+
case 0xc88949: // 49 89 c8 : mov r8, rcx
749+
case 0xc98949: // 49 89 c9 : mov r9, rcx
750+
case 0xca8949: // 49 89 ca : mov r10,rcx
751+
case 0xd08949: // 49 89 d0 : mov r8, rdx
752+
case 0xd18949: // 49 89 d1 : mov r9, rdx
753+
case 0xd28949: // 49 89 d2 : mov r10, rdx
754+
case 0xd38949: // 49 89 d3 : mov r11, rdx
714755
case 0xed854d: // 4d 85 ed : test r13, r13
715756
case 0xf6854d: // 4d 85 f6 : test r14, r14
716757
case 0xff854d: // 4d 85 ff : test r15, r15
@@ -721,6 +762,8 @@ static size_t GetInstructionSize(uptr address, size_t* rel_offset = nullptr) {
721762
case 0x588948: // 48 89 58 XX : mov QWORD PTR[rax + XX], rbx
722763
case 0xec8348: // 48 83 ec XX : sub rsp, XX
723764
case 0xf88349: // 49 83 f8 XX : cmp r8, XX
765+
case 0x148d4e: // 4e 8d 14 XX : lea r10, [rcx+r8*XX]
766+
case 0x398366: // 66 83 39 XX : cmp WORD PTR [rcx], XX
724767
return 4;
725768

726769
case 0x246483: // 83 64 24 XX YY : and DWORD PTR [rsp+XX], YY
@@ -735,6 +778,7 @@ static size_t GetInstructionSize(uptr address, size_t* rel_offset = nullptr) {
735778
return 6;
736779

737780
case 0xec8148: // 48 81 EC XX XX XX XX : sub rsp, XXXXXXXX
781+
case 0xc0c748: // 48 c7 c0 XX XX XX XX : mov rax, XX XX XX XX
738782
return 7;
739783

740784
// clang-format off
@@ -768,7 +812,13 @@ static size_t GetInstructionSize(uptr address, size_t* rel_offset = nullptr) {
768812
}
769813

770814
switch (*(u32*)(address)) {
815+
case 0x01b60f44: // 44 0f b6 01 : movzx r8d, BYTE PTR [rcx]
816+
case 0x09b60f44: // 44 0f b6 09 : movzx r9d, BYTE PTR [rcx]
817+
case 0x0ab60f44: // 44 0f b6 0a : movzx r8d, BYTE PTR [rdx]
818+
case 0x11b60f44: // 44 0f b6 11 : movzx r10d, BYTE PTR [rcx]
771819
case 0x1ab60f44: // 44 0f b6 1a : movzx r11d, BYTE PTR [rdx]
820+
case 0x11048d4c: // 4c 8d 04 11 : lea r8,[rcx+rdx*1]
821+
case 0xff488d49: // 49 8d 48 ff : lea rcx,[r8-0x1]
772822
return 4;
773823
case 0x24448b48: // 48 8b 44 24 XX : mov rax, QWORD ptr [rsp + XX]
774824
case 0x246c8948: // 48 89 6C 24 XX : mov QWORD ptr [rsp + XX], rbp
@@ -785,6 +835,29 @@ static size_t GetInstructionSize(uptr address, size_t* rel_offset = nullptr) {
785835
return 5;
786836
case 0x24648348: // 48 83 64 24 XX YY : and QWORD PTR [rsp + XX], YY
787837
return 6;
838+
case 0x24A48D48: // 48 8D A4 24 XX YY ZZ WW : lea rsp, [rsp + WWZZYYXX]
839+
return 8;
840+
}
841+
842+
switch (0xFFFFFFFFFFULL & *(u64*)(address)) {
843+
case 0xC07E0F4866: // 66 48 0F 7E C0 : movq rax,xmm0 (for wine fexp)
844+
case 0x0000441F0F: // 0F 1F 44 00 00 : nop DWORD PTR [rax+rax*1+0x0]
845+
return 5;
846+
}
847+
848+
switch (0xFFFFFFFFFFFFULL & *(u64*)(address)) {
849+
case 0x841f0f2e6666: // 66 66 2e 0f 1f 84 YY XX XX XX XX
850+
// data16 cs nop WORD PTR [rax+rax*1 + XX XX XX XX]
851+
return 11;
852+
}
853+
854+
switch (*(u64*)(address)) {
855+
case 0x010101010101b848: // 48 b8 01 01 01 01 01 01 01 01
856+
// movabs rax,0x101010101010101
857+
return 10;
858+
case 0x841f0f2e66666666: // 66 66 66 66 2e 0f 1f 84 YY XX XX XX XX
859+
// data16 data16 data16 cs nop WORD PTR [rax+rax*1 + XX XX XX XX]
860+
return 13;
788861
}
789862

790863
#else

0 commit comments

Comments
 (0)