From 65af9d037bf88e3cfc97b8ff61dfb19c4e874365 Mon Sep 17 00:00:00 2001 From: Denis Proshutinskii <36221916+jl0pd@users.noreply.github.com> Date: Mon, 1 Aug 2022 15:12:24 +0700 Subject: [PATCH] Add localloc empty stack verification (#73109) * Add localloc empty stack verification * Update error message * Add more tests * Fix tests Co-authored-by: Jan Kotas Co-authored-by: Dan Moseley --- .../tools/ILVerification/ILImporter.Verify.cs | 2 + src/coreclr/tools/ILVerification/Strings.resx | 3 ++ src/coreclr/tools/ILVerification/VerifierError.cs | 3 +- .../ilverify/ILTests/DefaultInterfaceMethod.il | 2 +- src/tests/ilverify/ILTests/LocalAllocTests.il | 43 ++++++++++++++++++++++ src/tests/ilverify/ILTests/LocalAllocTests.ilproj | 3 ++ 6 files changed, 54 insertions(+), 2 deletions(-) create mode 100644 src/tests/ilverify/ILTests/LocalAllocTests.il create mode 100644 src/tests/ilverify/ILTests/LocalAllocTests.ilproj diff --git a/src/coreclr/tools/ILVerification/ILImporter.Verify.cs b/src/coreclr/tools/ILVerification/ILImporter.Verify.cs index efa2b10..aefee9b 100644 --- a/src/coreclr/tools/ILVerification/ILImporter.Verify.cs +++ b/src/coreclr/tools/ILVerification/ILImporter.Verify.cs @@ -2582,6 +2582,8 @@ namespace Internal.IL var size = Pop(); + Check(_stackTop == 0, VerifierError.LocallocStackNotEmpty); + CheckIsInteger(size); Push(StackValue.CreatePrimitive(StackValueKind.NativeInt)); diff --git a/src/coreclr/tools/ILVerification/Strings.resx b/src/coreclr/tools/ILVerification/Strings.resx index 726cf6d..e38b197 100644 --- a/src/coreclr/tools/ILVerification/Strings.resx +++ b/src/coreclr/tools/ILVerification/Strings.resx @@ -447,4 +447,7 @@ Class implements interface but not method, Class: '{0}' Interface: '{1}' Missing method: '{2}'. + + Stack must be empty before localloc, except for the size item. + diff --git a/src/coreclr/tools/ILVerification/VerifierError.cs b/src/coreclr/tools/ILVerification/VerifierError.cs index 4be09b1..2d237aa 100644 --- a/src/coreclr/tools/ILVerification/VerifierError.cs +++ b/src/coreclr/tools/ILVerification/VerifierError.cs @@ -190,6 +190,7 @@ namespace ILVerify //IDS_E_GLOBAL "" //IDS_E_MDTOKEN "[mdToken=0x%x]" InterfaceImplHasDuplicate, // InterfaceImpl has a duplicate - InterfaceMethodNotImplemented // Class implements interface but not method + InterfaceMethodNotImplemented, // Class implements interface but not method + LocallocStackNotEmpty, // localloc requires that stack must be empty, except for 'size' argument } } diff --git a/src/tests/ilverify/ILTests/DefaultInterfaceMethod.il b/src/tests/ilverify/ILTests/DefaultInterfaceMethod.il index a33f5cd..afd4f59 100644 --- a/src/tests/ilverify/ILTests/DefaultInterfaceMethod.il +++ b/src/tests/ilverify/ILTests/DefaultInterfaceMethod.il @@ -107,7 +107,7 @@ } } -.class public auto ansi beforefieldinit ChildClassInheritsFromInterfaceWithDefaultImplementationWhereChildInterfaceReabstractsInterfaceMethod_InvalidType_InterfaceMethodNotImplemented +.class public auto ansi beforefieldinit ChildClassInheritsFromInterfaceWithDefaultImplementationWhereChildInterfaceReabstractsInterfaceMethod_InvalidType_InterfaceMethodNotImplemented@InterfaceMethodNotImplemented extends [System.Runtime]System.Object implements IReabstractDefaultImplementation, IInheritedDefaultImplInterface, IInterface { diff --git a/src/tests/ilverify/ILTests/LocalAllocTests.il b/src/tests/ilverify/ILTests/LocalAllocTests.il new file mode 100644 index 0000000..5789906 --- /dev/null +++ b/src/tests/ilverify/ILTests/LocalAllocTests.il @@ -0,0 +1,43 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +.assembly extern System.Runtime +{ +} + +.assembly extern LocalAllocTestsFriend +{ +} + +.assembly LocalAllocTests +{ +} + +.class public auto ansi beforefieldinit LocAllocTests + extends [System.Runtime]System.Object +{ + .method private hidebysig instance void Load.LocAllocShouldFailWhenStackNotEmpty_Invalid_Unverifiable.LocallocStackNotEmpty() cil managed + { + ldnull // pretend there's meaningfull value on stack + ldc.i4.2 // size parameter for localloc + localloc + pop // pop localloc pointer + pop // pop ldnull + ret + } + + .method private hidebysig instance void Load.LocAllocShouldFailWhenSizeIsAbsent_Invalid_Unverifiable.StackUnderflow() cil managed + { + localloc + pop // pop localloc pointer + ret + } + + .method private hidebysig instance void Load.LocAllocShouldSuccesWhenSizeIsPresent_Invalid_Unverifiable() cil managed + { + ldc.i4.2 // size parameter for localloc + localloc + pop // pop localloc pointer + ret + } +} diff --git a/src/tests/ilverify/ILTests/LocalAllocTests.ilproj b/src/tests/ilverify/ILTests/LocalAllocTests.ilproj new file mode 100644 index 0000000..8e8765d --- /dev/null +++ b/src/tests/ilverify/ILTests/LocalAllocTests.ilproj @@ -0,0 +1,3 @@ + + + -- 2.7.4