Store by-ref type annotation in trap and add tests

This commit is contained in:
Tamas Vajk
2021-01-11 22:11:55 +01:00
parent 2804f5cba9
commit 727412b26b
12 changed files with 1863 additions and 37 deletions

View File

@@ -125,9 +125,15 @@ namespace Semmle.Extraction.CIL.Entities
if (t is ByRefType brt)
{
t = brt.ElementType;
this.locals[l] = Cx.Populate(new LocalVariable(Cx, Implementation, l, t));
yield return this.locals[l];
yield return Tuples.cil_type_annotation(this.locals[l], TypeAnnotation.Ref);
}
else
{
this.locals[l] = Cx.Populate(new LocalVariable(Cx, Implementation, l, t));
yield return this.locals[l];
}
this.locals[l] = Cx.Populate(new LocalVariable(Cx, Implementation, l, t));
yield return this.locals[l];
}
}

View File

@@ -98,6 +98,7 @@ namespace Semmle.Extraction.CIL.Entities
if (retType is ByRefType byRefType)
{
retType = byRefType.ElementType;
yield return Tuples.cil_type_annotation(this, TypeAnnotation.Ref);
}
yield return Tuples.cil_function_pointer_return_type(this, retType);

View File

@@ -106,8 +106,14 @@ namespace Semmle.Extraction.CIL.Entities
if (t is ByRefType brt)
{
t = brt.ElementType;
var parameter = cx.Populate(new Parameter(cx, parameterizable, i++, t));
yield return parameter;
yield return Tuples.cil_type_annotation(parameter, TypeAnnotation.Ref);
}
else
{
yield return cx.Populate(new Parameter(cx, parameterizable, i++, t));
}
yield return cx.Populate(new Parameter(cx, parameterizable, i++, t));
}
}
@@ -122,6 +128,7 @@ namespace Semmle.Extraction.CIL.Entities
if (t is ByRefType brt)
{
t = brt.ElementType;
yield return Tuples.cil_type_annotation(this, TypeAnnotation.Ref);
}
yield return Tuples.cil_method(this, name, declaringType, t);
}

View File

@@ -65,6 +65,7 @@ namespace Semmle.Extraction.CIL.Entities
if (t is ByRefType brt)
{
t = brt.ElementType;
yield return Tuples.cil_type_annotation(this, TypeAnnotation.Ref);
}
yield return Tuples.cil_property(this, type, name, t);

View File

@@ -0,0 +1,11 @@
using System;
namespace Semmle.Extraction.CIL.Entities
{
[Flags]
public enum TypeAnnotation
{
None = 0,
Ref = 32
}
}

View File

@@ -197,6 +197,9 @@ namespace Semmle.Extraction.CIL
internal static Tuple cil_custom_modifiers(ICustomModifierReceiver receiver, Type modifier, bool isRequired) =>
new Tuple("cil_custom_modifiers", receiver, modifier, isRequired ? 1 : 0);
internal static Tuple cil_type_annotation(IEntity receiver, TypeAnnotation annotation) =>
new Tuple("cil_type_annotation", receiver, (int)annotation);
internal static Tuple containerparent(Folder parent, IFileOrFolder child) =>
new Tuple("containerparent", parent, child);

View File

@@ -1753,6 +1753,7 @@ cil_field(
@cil_member = @cil_method | @cil_type | @cil_field | @cil_property | @cil_event;
@cil_custom_modifier_receiver = @cil_method | @cil_property | @cil_parameter | @cil_field | @cil_function_pointer_type;
@cil_parameterizable = @cil_method | @cil_function_pointer_type;
@cil_has_type_annotation = @cil_stack_variable | @cil_property | @cil_method | @cil_function_pointer_type;
#keyset[parameterizable, index]
cil_parameter(
@@ -1773,6 +1774,10 @@ cil_custom_modifiers(
int modifier: @cil_type ref,
int kind: int ref); // modreq: 1, modopt: 0
cil_type_annotation(
int id: @cil_has_type_annotation ref,
int annotation: int ref);
cil_getter(unique int prop: @cil_property ref,
int method: @cil_method ref);

View File

@@ -1,29 +1,29 @@
fnptr
| file://:0:0:0:0 | delegate* managed<!0,Int32> | 1 | file://:0:0:0:0 | Int32 | 0 |
| file://:0:0:0:0 | delegate* managed<A,B> | 1 | file://:0:0:0:0 | B | 0 |
| file://:0:0:0:0 | delegate* managed<B,A> | 1 | file://:0:0:0:0 | A | 0 |
| file://:0:0:0:0 | delegate* managed<Int32&,Object& modreq(OutAttribute),Int32& modreq(InAttribute),Int32&> | 3 | file://:0:0:0:0 | Int32 | 0 |
| file://:0:0:0:0 | delegate* managed<Int32&,Object& modreq(OutAttribute),Int32> | 2 | file://:0:0:0:0 | Int32 | 0 |
| file://:0:0:0:0 | delegate* managed<Int32*,Void*> | 1 | file://:0:0:0:0 | Void* | 0 |
| file://:0:0:0:0 | delegate* managed<Int32> | 0 | file://:0:0:0:0 | Int32 | 0 |
| file://:0:0:0:0 | delegate* managed<Void*,Int32*> | 1 | file://:0:0:0:0 | Int32* | 0 |
| file://:0:0:0:0 | delegate* unmanaged[StdCall]<Int32&,Object& modreq(OutAttribute),!0,Void> | 3 | file://:0:0:0:0 | void | 2 |
| delegate* managed<!0,Int32> | 1 | Int32 | 0 |
| delegate* managed<A,B> | 1 | B | 0 |
| delegate* managed<B,A> | 1 | A | 0 |
| delegate* managed<Int32&,Object& modreq(OutAttribute),Int32& modreq(InAttribute),Int32&> | 3 | Int32& | 0 |
| delegate* managed<Int32&,Object& modreq(OutAttribute),Int32> | 2 | Int32 | 0 |
| delegate* managed<Int32*,Void*> | 1 | Void* | 0 |
| delegate* managed<Int32> | 0 | Int32 | 0 |
| delegate* managed<Void*,Int32*> | 1 | Int32* | 0 |
| delegate* unmanaged[StdCall]<Int32&,Object& modreq(OutAttribute),!0,Void> | 3 | void | 2 |
params
| file://:0:0:0:0 | delegate* managed<!0,Int32> | 0 | file://:0:0:0:0 | Parameter 0 of delegate* managed<!0,Int32> | fnptr.dll:0:0:0:0 | !0 |
| file://:0:0:0:0 | delegate* managed<A,B> | 0 | file://:0:0:0:0 | Parameter 0 of delegate* managed<A,B> | file://:0:0:0:0 | A |
| file://:0:0:0:0 | delegate* managed<B,A> | 0 | file://:0:0:0:0 | Parameter 0 of delegate* managed<B,A> | file://:0:0:0:0 | B |
| file://:0:0:0:0 | delegate* managed<Int32&,Object& modreq(OutAttribute),Int32& modreq(InAttribute),Int32&> | 0 | file://:0:0:0:0 | Parameter 0 of delegate* managed<Int32&,Object& modreq(OutAttribute),Int32& modreq(InAttribute),Int32&> | file://:0:0:0:0 | Int32 |
| file://:0:0:0:0 | delegate* managed<Int32&,Object& modreq(OutAttribute),Int32& modreq(InAttribute),Int32&> | 1 | file://:0:0:0:0 | Parameter 1 of delegate* managed<Int32&,Object& modreq(OutAttribute),Int32& modreq(InAttribute),Int32&> | file://:0:0:0:0 | Object |
| file://:0:0:0:0 | delegate* managed<Int32&,Object& modreq(OutAttribute),Int32& modreq(InAttribute),Int32&> | 2 | file://:0:0:0:0 | Parameter 2 of delegate* managed<Int32&,Object& modreq(OutAttribute),Int32& modreq(InAttribute),Int32&> | file://:0:0:0:0 | Int32 |
| file://:0:0:0:0 | delegate* managed<Int32&,Object& modreq(OutAttribute),Int32> | 0 | file://:0:0:0:0 | Parameter 0 of delegate* managed<Int32&,Object& modreq(OutAttribute),Int32> | file://:0:0:0:0 | Int32 |
| file://:0:0:0:0 | delegate* managed<Int32&,Object& modreq(OutAttribute),Int32> | 1 | file://:0:0:0:0 | Parameter 1 of delegate* managed<Int32&,Object& modreq(OutAttribute),Int32> | file://:0:0:0:0 | Object |
| file://:0:0:0:0 | delegate* managed<Int32*,Void*> | 0 | file://:0:0:0:0 | Parameter 0 of delegate* managed<Int32*,Void*> | file://:0:0:0:0 | Int32* |
| file://:0:0:0:0 | delegate* managed<Void*,Int32*> | 0 | file://:0:0:0:0 | Parameter 0 of delegate* managed<Void*,Int32*> | file://:0:0:0:0 | Void* |
| file://:0:0:0:0 | delegate* unmanaged[StdCall]<Int32&,Object& modreq(OutAttribute),!0,Void> | 0 | file://:0:0:0:0 | Parameter 0 of delegate* unmanaged[StdCall]<Int32&,Object& modreq(OutAttribute),!0,Void> | file://:0:0:0:0 | Int32 |
| file://:0:0:0:0 | delegate* unmanaged[StdCall]<Int32&,Object& modreq(OutAttribute),!0,Void> | 1 | file://:0:0:0:0 | Parameter 1 of delegate* unmanaged[StdCall]<Int32&,Object& modreq(OutAttribute),!0,Void> | file://:0:0:0:0 | Object |
| file://:0:0:0:0 | delegate* unmanaged[StdCall]<Int32&,Object& modreq(OutAttribute),!0,Void> | 2 | file://:0:0:0:0 | Parameter 2 of delegate* unmanaged[StdCall]<Int32&,Object& modreq(OutAttribute),!0,Void> | fnptr.dll:0:0:0:0 | !0 |
| delegate* managed<!0,Int32> | 0 | Parameter 0 of delegate* managed<!0,Int32> | !0 |
| delegate* managed<A,B> | 0 | Parameter 0 of delegate* managed<A,B> | A |
| delegate* managed<B,A> | 0 | Parameter 0 of delegate* managed<B,A> | B |
| delegate* managed<Int32&,Object& modreq(OutAttribute),Int32& modreq(InAttribute),Int32&> | 0 | Parameter 0 of delegate* managed<Int32&,Object& modreq(OutAttribute),Int32& modreq(InAttribute),Int32&> | Int32& |
| delegate* managed<Int32&,Object& modreq(OutAttribute),Int32& modreq(InAttribute),Int32&> | 1 | Parameter 1 of delegate* managed<Int32&,Object& modreq(OutAttribute),Int32& modreq(InAttribute),Int32&> | Object& |
| delegate* managed<Int32&,Object& modreq(OutAttribute),Int32& modreq(InAttribute),Int32&> | 2 | Parameter 2 of delegate* managed<Int32&,Object& modreq(OutAttribute),Int32& modreq(InAttribute),Int32&> | Int32& |
| delegate* managed<Int32&,Object& modreq(OutAttribute),Int32> | 0 | Parameter 0 of delegate* managed<Int32&,Object& modreq(OutAttribute),Int32> | Int32& |
| delegate* managed<Int32&,Object& modreq(OutAttribute),Int32> | 1 | Parameter 1 of delegate* managed<Int32&,Object& modreq(OutAttribute),Int32> | Object& |
| delegate* managed<Int32*,Void*> | 0 | Parameter 0 of delegate* managed<Int32*,Void*> | Int32* |
| delegate* managed<Void*,Int32*> | 0 | Parameter 0 of delegate* managed<Void*,Int32*> | Void* |
| delegate* unmanaged[StdCall]<Int32&,Object& modreq(OutAttribute),!0,Void> | 0 | Parameter 0 of delegate* unmanaged[StdCall]<Int32&,Object& modreq(OutAttribute),!0,Void> | Int32& |
| delegate* unmanaged[StdCall]<Int32&,Object& modreq(OutAttribute),!0,Void> | 1 | Parameter 1 of delegate* unmanaged[StdCall]<Int32&,Object& modreq(OutAttribute),!0,Void> | Object& |
| delegate* unmanaged[StdCall]<Int32&,Object& modreq(OutAttribute),!0,Void> | 2 | Parameter 2 of delegate* unmanaged[StdCall]<Int32&,Object& modreq(OutAttribute),!0,Void> | !0 |
modifiers
| file://:0:0:0:0 | delegate* managed<Int32&,Object& modreq(OutAttribute),Int32& modreq(InAttribute),Int32&> | System.Runtime.InteropServices.InAttribute | modreq |
| file://:0:0:0:0 | delegate* managed<Int32&,Object& modreq(OutAttribute),Int32& modreq(InAttribute),Int32&> | System.Runtime.InteropServices.OutAttribute | modreq |
| file://:0:0:0:0 | delegate* managed<Int32&,Object& modreq(OutAttribute),Int32> | System.Runtime.InteropServices.OutAttribute | modreq |
| file://:0:0:0:0 | delegate* unmanaged[StdCall]<Int32&,Object& modreq(OutAttribute),!0,Void> | System.Runtime.InteropServices.OutAttribute | modreq |
| delegate* managed<Int32&,Object& modreq(OutAttribute),Int32& modreq(InAttribute),Int32&> | System.Runtime.InteropServices.InAttribute | modreq |
| delegate* managed<Int32&,Object& modreq(OutAttribute),Int32& modreq(InAttribute),Int32&> | System.Runtime.InteropServices.OutAttribute | modreq |
| delegate* managed<Int32&,Object& modreq(OutAttribute),Int32> | System.Runtime.InteropServices.OutAttribute | modreq |
| delegate* unmanaged[StdCall]<Int32&,Object& modreq(OutAttribute),!0,Void> | System.Runtime.InteropServices.OutAttribute | modreq |

View File

@@ -4,18 +4,28 @@ import semmle.code.cil.Type
bindingset[kind]
private string getKind(int kind) { if kind = 1 then result = "modreq" else result = "modopt" }
query predicate fnptr(FunctionPointerType fn, int paramCount, Type returnType, int callingConvention) {
paramCount = fn.getNumberOfParameters() and
returnType = fn.getReturnType() and
callingConvention = fn.getCallingConvention()
private string getAnnotatedType(Type t, Element e) {
cil_type_annotation(e, 32) and result = t.toString() + "&"
or
not cil_type_annotation(e, 32) and result = t.toString()
}
query predicate params(FunctionPointerType fn, int i, Parameter p, Type t) {
fn.getParameter(i) = p and p.getType() = t
query predicate fnptr(string fnptr, int paramCount, string returnType, int callingConvention) {
exists(FunctionPointerType fn | fnptr = fn.toString() |
paramCount = fn.getNumberOfParameters() and
returnType = getAnnotatedType(fn.getReturnType(), fn) and
callingConvention = fn.getCallingConvention()
)
}
query predicate modifiers(FunctionPointerType fn, string modifier, string sKind) {
exists(Type modType, int kind |
query predicate params(string fnptr, int i, string param, string t) {
exists(FunctionPointerType fn, Parameter p | fnptr = fn.toString() and param = p.toString() |
fn.getParameter(i) = p and t = getAnnotatedType(p.getType(), p)
)
}
query predicate modifiers(string fnptr, string modifier, string sKind) {
exists(Type modType, int kind, FunctionPointerType fn | fnptr = fn.toString() |
cil_custom_modifiers(fn, modType, kind) and
modType.getQualifiedName() = modifier and
sKind = getKind(kind)

View File

@@ -0,0 +1,10 @@
// semmle-extractor-options: --cil
using System;
class Test
{
static void Main(string[] args)
{
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,25 @@
import cil
import semmle.code.cil.Type
private string elementType(Element e) {
e instanceof Method and result = "method"
or
e instanceof Property and result = "property"
or
e instanceof Parameter and result = "parameter"
or
e instanceof LocalVariable and result = "local"
or
e instanceof FunctionPointerType and result = "fnptr"
or
not e instanceof Method and
not e instanceof Property and
not e instanceof Parameter and
not e instanceof LocalVariable and
not e instanceof FunctionPointerType and
result = "other"
}
from Element e, int i
where cil_type_annotation(e, i)
select e.toString(), elementType(e), i