Skip to content

Commit 156495a

Browse files
committed
CIL: Support parameters and loading of parameters.
1 parent 24667c0 commit 156495a

9 files changed

Lines changed: 178 additions & 13 deletions

File tree

binary/extractor/cil/Semmle.Extraction.CSharp.IL/ILExtractor.cs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,12 @@ private void ExtractMethod(MethodDefinition method, int typeId) {
8585
if (method.HasBody) {
8686
ExtractMethodBody(method, methodId);
8787
}
88+
89+
for(int i = 0; i < method.Parameters.Count; i++) {
90+
var param = method.Parameters[i];
91+
var paramId = trap.GetId();
92+
trap.WriteTuple("il_parameter", paramId, methodId, i, param.Name);
93+
}
8894
}
8995

9096
private void ExtractMethodBody(MethodDefinition method, int methodId) {

binary/ql/lib/semmle/code/binary/ast/instructions.qll

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ private import Headers
44
private import Sections
55
private import codeql.util.Unit
66

7-
private class TElement = @x86_instruction or @operand or @il_instruction or @method;
7+
private class TElement = @x86_instruction or @operand or @il_instruction or @method or @il_parameter;
88

99
class Element extends TElement {
1010
final string toString() { none() }

binary/ql/lib/semmle/code/binary/ast/internal/CilInstructions.qll

Lines changed: 37 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,16 @@ class CilVariable instanceof @method {
55
string toString() { none() }
66
}
77

8+
class CilParameter instanceof @il_parameter {
9+
string toString() { result = this.getName() }
10+
11+
CilMethod getMethod() { il_parameter(this, result, _, _) }
12+
13+
int getIndex() { il_parameter(this, _, result, _) }
14+
15+
string getName() { il_parameter(this, _, _, result) }
16+
}
17+
818
class CilMethod extends @method {
919
string getName() { methods(this, result, _, _) }
1020

@@ -21,6 +31,11 @@ class CilMethod extends @method {
2131
CilInstruction getInstruction(int i) { il_instruction_parent(result, i, this) }
2232

2333
CilVariable getVariable(int i) { none() } // TODO
34+
35+
CilParameter getParameter(int i) {
36+
result.getMethod() = this and
37+
result.getIndex() = i
38+
}
2439
}
2540

2641
pragma[nomagic]
@@ -77,13 +92,21 @@ class CilNop extends @il_nop, CilInstruction { }
7792

7893
class CilBreak extends @il_break, CilInstruction { }
7994

80-
class CilLdarg_0 extends @il_ldarg_0, CilInstruction { }
95+
class CilLdarg_0 extends @il_ldarg_0, CilLoadArgument {
96+
override int getArgumentIndex() { result = 0 }
97+
}
8198

82-
class CilLdarg_1 extends @il_ldarg_1, CilInstruction { }
99+
class CilLdarg_1 extends @il_ldarg_1, CilLoadArgument {
100+
override int getArgumentIndex() { result = 1 }
101+
}
83102

84-
class CilLdarg_2 extends @il_ldarg_2, CilInstruction { }
103+
class CilLdarg_2 extends @il_ldarg_2, CilLoadArgument {
104+
override int getArgumentIndex() { result = 2 }
105+
}
85106

86-
class CilLdarg_3 extends @il_ldarg_3, CilInstruction { }
107+
class CilLdarg_3 extends @il_ldarg_3, CilLoadArgument {
108+
override int getArgumentIndex() { result = 3 }
109+
}
87110

88111
class CilLdloc_0 extends @il_ldloc_0, CilLoadLocal {
89112
override int getLocalVariableIndex() { result = 0 }
@@ -117,11 +140,15 @@ class CilStloc_3 extends @il_stloc_3, CilStoreLocal {
117140
override int getLocalVariableIndex() { result = 3 }
118141
}
119142

120-
abstract class CilLoadArgument extends CilInstruction { }
143+
abstract class CilLoadArgument extends CilInstruction {
144+
abstract int getArgumentIndex();
145+
}
121146

122-
class CilLdarg_S extends @il_ldarg_S, CilLoadArgument { }
147+
class CilLdarg_S extends @il_ldarg_S, CilLoadArgument {
148+
override int getArgumentIndex() { il_operand_byte(this, result) }
149+
}
123150

124-
class CilLdarga_S extends @il_ldarga_S, CilLoadArgument { }
151+
class CilLdarga_S extends @il_ldarga_S, CilInstruction { }
125152

126153
abstract class CilStoreArgument extends CilInstruction { }
127154

@@ -677,7 +704,9 @@ class CilLdftn extends @il_ldftn, CilInstruction { }
677704

678705
class CilLdvirtftn extends @il_ldvirtftn, CilInstruction { }
679706

680-
class CilLdarg extends @il_ldarg, CilInstruction { }
707+
class CilLdarg extends @il_ldarg, CilLoadArgument {
708+
override int getArgumentIndex() { il_operand_int(this, result) }
709+
}
681710

682711
class CilLdarga extends @il_ldarga, CilInstruction { }
683712

binary/ql/lib/semmle/code/binary/ast/ir/internal/Instruction0/TempVariableTag.qll

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,8 @@ newtype TTempVariableTag =
3131
CilUnconditionalBranchRefVarTag() or
3232
CallReturnValueTag() or
3333
CilCallTargetVarTag() or
34-
CilLoadStringVarTag()
34+
CilLoadStringVarTag() or
35+
CilLoadArgVarTag()
3536

3637
class TempVariableTag extends TTempVariableTag {
3738
string toString() {
@@ -133,5 +134,8 @@ class TempVariableTag extends TTempVariableTag {
133134
or
134135
this = CilLoadStringVarTag() and
135136
result = "ldstr"
137+
or
138+
this = CilLoadArgVarTag() and
139+
result = "ldarg"
136140
}
137141
}

binary/ql/lib/semmle/code/binary/ast/ir/internal/Instruction0/TranslatedElement.qll

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,8 @@ private predicate shouldTranslateCilInstr(Raw::CilInstruction instr) { any() }
2626

2727
private predicate shouldTranslateMethod(Raw::CilMethod m) { any() }
2828

29+
private predicate shouldTranslateCilParameter(Raw::CilParameter p) { any() }
30+
2931
newtype TTranslatedElement =
3032
TTranslatedX86Function(Raw::X86Instruction entry) {
3133
shouldTranslateX86Instr(entry) and
@@ -91,7 +93,9 @@ newtype TTranslatedElement =
9193
} or
9294
TTranslatedCilRet(Raw::CilIl_ret ret) { shouldTranslateCilInstr(ret) } or
9395
TTranslatedCilCall(Raw::CilCall call) { shouldTranslateCilInstr(call) } or
94-
TTranslatedCilLoadString(Raw::CilLdstr ldstr) { shouldTranslateCilInstr(ldstr) }
96+
TTranslatedCilLoadString(Raw::CilLdstr ldstr) { shouldTranslateCilInstr(ldstr) } or
97+
TTranslatedCilParameter(Raw::CilParameter param) { shouldTranslateCilParameter(param) } or
98+
TTranslatedCilLoadArg(Raw::CilLoadArgument ldstr) { shouldTranslateCilInstr(ldstr) }
9599

96100
TranslatedElement getTranslatedElement(Raw::Element raw) {
97101
result.getRawElement() = raw and

binary/ql/lib/semmle/code/binary/ast/ir/internal/Instruction0/TranslatedFunction.qll

Lines changed: 66 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -127,6 +127,54 @@ class TranslatedX86Function extends TranslatedFunction, TTranslatedX86Function {
127127
}
128128
}
129129

130+
class TranslatedCilParameter extends TranslatedElement, TTranslatedCilParameter {
131+
Raw::CilParameter p;
132+
133+
TranslatedCilParameter() { this = TTranslatedCilParameter(p) }
134+
135+
override Raw::Element getRawElement() { result = p }
136+
137+
override Variable getResultVariable() { none() }
138+
139+
override TranslatedFunction getEnclosingFunction() {
140+
result = getTranslatedFunction(p.getMethod())
141+
}
142+
143+
override predicate hasInstruction(Opcode opcode, InstructionTag tag, Option<Variable>::Option v) {
144+
opcode instanceof Opcode::Init and
145+
tag = SingleTag() and
146+
v.asSome() = this.getLocalVariable(CilParameterVarTag(p.getIndex()))
147+
}
148+
149+
override predicate hasLocalVariable(LocalVariableTag tag) {
150+
tag = CilParameterVarTag(p.getIndex())
151+
}
152+
153+
override string getDumpId() { result = p.getName() }
154+
155+
override string toString() { result = "Translation of " + p.getName() }
156+
157+
override Variable getVariableOperand(InstructionTag tag, OperandTag operandTag) { none() }
158+
159+
override predicate producesResult() { any() }
160+
161+
final override Instruction getSuccessor(InstructionTag tag, SuccessorType succType) {
162+
tag = SingleTag() and
163+
result = this.getEnclosingFunction().getChildSuccessor(this, succType)
164+
}
165+
166+
final override Instruction getChildSuccessor(TranslatedElement child, SuccessorType succType) {
167+
none()
168+
}
169+
170+
Instruction getEntry() { result = this.getInstruction(SingleTag()) }
171+
}
172+
173+
private TranslatedCilParameter getTranslatedParameter(Raw::CilParameter p) {
174+
result.getRawElement() = p and
175+
result.producesResult()
176+
}
177+
130178
class TranslatedCilMethod extends TranslatedFunction, TTranslatedCilMethod {
131179
Raw::CilMethod method;
132180

@@ -142,7 +190,21 @@ class TranslatedCilMethod extends TranslatedFunction, TTranslatedCilMethod {
142190

143191
override Instruction getBodySuccessor(InstructionTag tag, SuccessorType succType) { none() }
144192

145-
override Instruction getChildSuccessor(TranslatedElement child, SuccessorType succType) { none() }
193+
private TranslatedCilParameter getParameter(int index) {
194+
result = getTranslatedParameter(method.getParameter(index))
195+
}
196+
197+
override Instruction getChildSuccessor(TranslatedElement child, SuccessorType succType) {
198+
exists(int index |
199+
child = this.getParameter(index) and
200+
succType instanceof DirectSuccessor
201+
|
202+
result = this.getParameter(index + 1).getEntry()
203+
or
204+
not exists(this.getParameter(index + 1)) and
205+
result = getTranslatedInstruction(method.getInstruction(0)).getEntry()
206+
)
207+
}
146208

147209
override string getName() { result = method.getName() }
148210

@@ -151,6 +213,9 @@ class TranslatedCilMethod extends TranslatedFunction, TTranslatedCilMethod {
151213
override predicate isExported() { none() }
152214

153215
override Instruction getBodyEntry() {
216+
result = this.getParameter(0).getEntry()
217+
or
218+
not exists(this.getParameter(0)) and
154219
result = getTranslatedInstruction(method.getInstruction(0)).getEntry()
155220
}
156221

binary/ql/lib/semmle/code/binary/ast/ir/internal/Instruction0/TranslatedInstruction.qll

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2328,3 +2328,47 @@ class TranslatedCilLoadString extends TranslatedCilInstruction, TTranslatedCilLo
23282328
result = getTranslatedCilInstruction(instr.getABackwardPredecessor()).getStackElement(i - 1)
23292329
}
23302330
}
2331+
2332+
class TranslatedCilLoadArg extends TranslatedCilInstruction, TTranslatedCilLoadArg {
2333+
override Raw::CilLoadArgument instr;
2334+
2335+
TranslatedCilLoadArg() { this = TTranslatedCilLoadArg(instr) }
2336+
2337+
final override predicate hasInstruction(
2338+
Opcode opcode, InstructionTag tag, Option<Variable>::Option v
2339+
) {
2340+
opcode instanceof Opcode::Copy and
2341+
tag = SingleTag() and
2342+
v.asSome() = this.getVariable(CilLoadArgVarTag())
2343+
}
2344+
2345+
override predicate hasTempVariable(TempVariableTag tag) { tag = CilLoadArgVarTag() }
2346+
2347+
override predicate producesResult() { any() }
2348+
2349+
override Variable getVariableOperand(InstructionTag tag, OperandTag operandTag) {
2350+
tag = SingleTag() and
2351+
operandTag instanceof UnaryTag and
2352+
result = this.getLocalVariable(CilParameterVarTag(instr.getArgumentIndex()))
2353+
}
2354+
2355+
override Instruction getChildSuccessor(TranslatedElement child, SuccessorType succType) { none() }
2356+
2357+
override Instruction getSuccessor(InstructionTag tag, SuccessorType succType) {
2358+
tag = SingleTag() and
2359+
succType instanceof DirectSuccessor and
2360+
result = getTranslatedInstruction(instr.getASuccessor()).getEntry()
2361+
}
2362+
2363+
override Instruction getEntry() { result = this.getInstruction(SingleTag()) }
2364+
2365+
override Variable getResultVariable() { result = this.getVariable(CilLoadArgVarTag()) }
2366+
2367+
final override Variable getStackElement(int i) {
2368+
i = 0 and
2369+
result = this.getInstruction(SingleTag()).getResultVariable()
2370+
or
2371+
i > 0 and
2372+
result = getTranslatedCilInstruction(instr.getABackwardPredecessor()).getStackElement(i - 1)
2373+
}
2374+
}

binary/ql/lib/semmle/code/binary/ast/ir/internal/Tags.qll

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,8 @@ private import semmle.code.binary.ast.internal.instructions
66
newtype LocalVariableTag =
77
CmpRegisterTag() or
88
X86RegisterTag(X86Register r) or
9-
StlocVarTag(int index) { any(CilStoreLocal stloc).getLocalVariableIndex() = index }
9+
StlocVarTag(int index) { any(CilStoreLocal stloc).getLocalVariableIndex() = index } or
10+
CilParameterVarTag(int index) { any(CilParameter p).getIndex() = index }
1011

1112
string stringOfLocalVariableTag(LocalVariableTag tag) {
1213
tag = CmpRegisterTag() and
@@ -21,4 +22,9 @@ string stringOfLocalVariableTag(LocalVariableTag tag) {
2122
tag = X86RegisterTag(r) and
2223
result = r.toString()
2324
)
25+
or
26+
exists(int index |
27+
tag = CilParameterVarTag(index) and
28+
result = "param_" + index.toString()
29+
)
2430
}

binary/ql/lib/semmlecode.binary.dbscheme

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2420,6 +2420,13 @@ il_call_has_return_value(
24202420
int instruction: @il_instruction ref
24212421
);
24222422

2423+
il_parameter(
2424+
unique int p: @il_parameter,
2425+
int method: @method ref,
2426+
int index: int ref,
2427+
string name: string ref
2428+
);
2429+
24232430
/**
24242431
* Unresolved method call targets.
24252432
* The target_method_name is the fully qualified name of the called method.

0 commit comments

Comments
 (0)