Skip to content

Commit 85d9007

Browse files
committed
Binary: Translate 'CilLdfld' to IR.
1 parent 03a907e commit 85d9007

6 files changed

Lines changed: 124 additions & 7 deletions

File tree

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

Lines changed: 23 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -624,19 +624,38 @@ class CilUnbox extends @il_unbox, CilInstruction { }
624624
class CilThrow extends @il_throw, CilInstruction { }
625625

626626
/** An instruction that loads a field value. */
627-
abstract class CilLoadFieldInstruction extends CilInstruction { }
627+
abstract class CilLoadFieldInstruction extends CilInstruction {
628+
CilField getField() {
629+
exists(string declaringTypeName, string fieldName |
630+
il_field_operand(this, declaringTypeName, fieldName) and
631+
fieldHasDeclaringTypeNameAndName(declaringTypeName, fieldName, result)
632+
)
633+
}
634+
635+
predicate isStatic() { none() }
636+
637+
predicate onlyComputesAddress() { none() }
638+
}
628639

629640
/** An instruction that loads an instance field value. */
630641
class CilLdfld extends @il_ldfld, CilLoadFieldInstruction { }
631642

632643
/** An instruction that loads the address of an instance field. */
633-
class CilLdflda extends @il_ldflda, CilLoadFieldInstruction { }
644+
class CilLdflda extends @il_ldflda, CilLoadFieldInstruction {
645+
final override predicate onlyComputesAddress() { any() }
646+
}
634647

635648
/** An instruction that loads a static field value. */
636-
class CilLdsfld extends @il_ldsfld, CilLoadFieldInstruction { }
649+
class CilLdsfld extends @il_ldsfld, CilLoadFieldInstruction {
650+
final override predicate isStatic() { any() }
651+
}
637652

638653
/** An instruction that loads the address of a static field. */
639-
class CilLdsflda extends @il_ldsflda, CilLoadFieldInstruction { }
654+
class CilLdsflda extends @il_ldsflda, CilLoadFieldInstruction {
655+
final override predicate isStatic() { any() }
656+
657+
final override predicate onlyComputesAddress() { any() }
658+
}
640659

641660
pragma[nomagic]
642661
private predicate fieldHasDeclaringTypeNameAndName(

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

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,9 @@ newtype TInstructionTag =
5858
CilNewObjCallTag() or
5959
CilNewObjExternalRefTag() or
6060
CilStoreFieldAddressTag() or
61-
CilStoreFieldStoreTag()
61+
CilStoreFieldStoreTag() or
62+
CilLoadFieldAddressTag() or
63+
CilLoadFieldLoadTag()
6264

6365
class InstructionTag extends TInstructionTag {
6466
final string toString() {
@@ -216,6 +218,12 @@ class InstructionTag extends TInstructionTag {
216218
or
217219
this = CilStoreFieldStoreTag() and
218220
result = "CilStoreFieldStore"
221+
or
222+
this = CilLoadFieldAddressTag() and
223+
result = "CilLoadFieldAddress"
224+
or
225+
this = CilLoadFieldLoadTag() and
226+
result = "CilLoadFieldLoad"
219227
}
220228
}
221229

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

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,9 @@ newtype TTempVariableTag =
3333
CilNewObjInitVarTag() or
3434
CilNewObjCallExternalVarTag() or
3535
CilDupVarTag() or
36-
CilStoreFieldAddressVarTag()
36+
CilStoreFieldAddressVarTag() or
37+
CilLoadFieldAddressVarTag() or
38+
CilLoadFieldLoadVarTag()
3739

3840
class TempVariableTag extends TTempVariableTag {
3941
string toString() {
@@ -141,5 +143,11 @@ class TempVariableTag extends TTempVariableTag {
141143
or
142144
this = CilStoreFieldAddressVarTag() and
143145
result = "stfldaddr"
146+
or
147+
this = CilLoadFieldAddressVarTag() and
148+
result = "ldfldaddr"
149+
or
150+
this = CilLoadFieldLoadVarTag() and
151+
result = "ldfld"
144152
}
145153
}

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

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -135,7 +135,8 @@ newtype TTranslatedElement =
135135
TTranslatedCilType(Raw::CilType type) { shouldTranslatedCilType(type) } or
136136
TTranslatedNewObject(Raw::CilNewobj newObj) { shouldTranslateCilInstr(newObj) } or
137137
TTranslatedDup(Raw::CilDup dup) { shouldTranslateCilInstr(dup) } or
138-
TTranslatedCilStoreField(Raw::CilStfld store) { shouldTranslateCilInstr(store) }
138+
TTranslatedCilStoreField(Raw::CilStfld store) { shouldTranslateCilInstr(store) } or
139+
TTranslatedCilLoadField(Raw::CilLdfld load) { shouldTranslateCilInstr(load) }
139140

140141
TranslatedElement getTranslatedElement(Raw::Element raw) {
141142
result.getRawElement() = raw and

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

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2616,3 +2616,66 @@ class TranslatedCilStoreField extends TranslatedCilInstruction, TTranslatedCilSt
26162616
result = getTranslatedCilInstruction(instr.getABackwardPredecessor()).getStackElement(i + 2)
26172617
}
26182618
}
2619+
2620+
class TranslatedCilLoadField extends TranslatedCilInstruction, TTranslatedCilLoadField {
2621+
override Raw::CilLdfld instr;
2622+
2623+
TranslatedCilLoadField() { this = TTranslatedCilLoadField(instr) }
2624+
2625+
final override predicate hasInstruction(
2626+
Opcode opcode, InstructionTag tag, Option<Variable>::Option v
2627+
) {
2628+
opcode instanceof Opcode::FieldAddress and
2629+
tag = CilLoadFieldAddressTag() and
2630+
v.asSome() = this.getTempVariable(CilLoadFieldAddressVarTag())
2631+
or
2632+
opcode instanceof Opcode::Load and
2633+
tag = CilLoadFieldLoadTag() and
2634+
v.asSome() = this.getTempVariable(CilLoadFieldLoadVarTag())
2635+
}
2636+
2637+
override predicate hasTempVariable(TempVariableTag tag) {
2638+
tag = CilLoadFieldAddressVarTag() or tag = CilLoadFieldLoadVarTag()
2639+
}
2640+
2641+
override predicate producesResult() { any() }
2642+
2643+
override Variable getVariableOperand(InstructionTag tag, OperandTag operandTag) {
2644+
tag = CilLoadFieldAddressTag() and
2645+
operandTag instanceof UnaryTag and
2646+
result = getTranslatedCilInstruction(instr.getABackwardPredecessor()).getStackElement(0)
2647+
or
2648+
tag = CilLoadFieldLoadTag() and
2649+
operandTag instanceof LoadAddressTag and
2650+
result = this.getInstruction(CilLoadFieldAddressTag()).getResultVariable()
2651+
}
2652+
2653+
final override string getFieldName(InstructionTag tag) {
2654+
tag = CilLoadFieldAddressTag() and
2655+
result = instr.getField().getName()
2656+
}
2657+
2658+
override Instruction getChildSuccessor(TranslatedElement child, SuccessorType succType) { none() }
2659+
2660+
override Instruction getSuccessor(InstructionTag tag, SuccessorType succType) {
2661+
tag = CilLoadFieldAddressTag() and
2662+
succType instanceof DirectSuccessor and
2663+
result = this.getInstruction(CilLoadFieldLoadTag())
2664+
or
2665+
tag = CilLoadFieldLoadTag() and
2666+
succType instanceof DirectSuccessor and
2667+
result = getTranslatedInstruction(instr.getASuccessor()).getEntry()
2668+
}
2669+
2670+
override Instruction getEntry() { result = this.getInstruction(CilLoadFieldAddressTag()) }
2671+
2672+
override Variable getResultVariable() { result = this.getTempVariable(CilLoadFieldLoadVarTag()) }
2673+
2674+
final override Variable getStackElement(int i) {
2675+
i = 0 and
2676+
result = this.getInstruction(CilLoadFieldLoadTag()).getResultVariable()
2677+
or
2678+
i > 0 and
2679+
result = getTranslatedCilInstruction(instr.getABackwardPredecessor()).getStackElement(i)
2680+
}
2681+
}

binary/test-inputs/TestAssembly/SimpleClass.cs

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -182,4 +182,22 @@ public string SwitchTest(int value)
182182
}
183183
}
184184
}
185+
186+
public class WriteToField
187+
{
188+
public int value;
189+
public WriteToField(int x)
190+
{
191+
value = x;
192+
}
193+
}
194+
195+
public class B
196+
{
197+
public static int LoadFromField()
198+
{
199+
WriteToField a = new WriteToField(5);
200+
return a.value;
201+
}
202+
}
185203
}

0 commit comments

Comments
 (0)