Skip to content

Commit c5da111

Browse files
committed
Binary/X86: Support arguments and parameters in X86.
1 parent 9c63a86 commit c5da111

18 files changed

Lines changed: 771 additions & 409 deletions

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

Lines changed: 28 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -52,13 +52,23 @@ private module Pre {
5252
}
5353
}
5454

55-
class BaseX86Register extends Internal::X86Register { }
55+
class BaseX86Register extends Internal::X86Register {
56+
BaseX86Register getASubRegister() { result = super.getASubRegister() }
57+
}
58+
59+
class BaseRipRegister extends BaseX86Register instanceof Internal::RipRegister { }
60+
61+
class BaseRspRegister extends BaseX86Register instanceof Internal::RspRegister { }
62+
63+
class BaseRbpRegister extends BaseX86Register instanceof Internal::RbpRegister { }
64+
65+
class BaseRcxRegister extends BaseX86Register instanceof Internal::RcxRegister { }
5666

57-
class BaseRipRegister extends BaseX86Register, Internal::RipRegister { }
67+
class BaseRdxRegister extends BaseX86Register instanceof Internal::RdxRegister { }
5868

59-
class BaseRspRegister extends BaseX86Register, Internal::RspRegister { }
69+
class BaseR8Register extends BaseX86Register instanceof Internal::R8Register { }
6070

61-
class BaseRbpRegister extends BaseX86Register, Internal::RbpRegister { }
71+
class BaseR9Register extends BaseX86Register instanceof Internal::R9Register { }
6272

6373
class BaseX86Operand extends Internal::X86Operand { }
6474

@@ -198,13 +208,23 @@ private module Input implements Internal::InstructionInputSig {
198208
result = Pre::PreInput::getJumpTarget(b)
199209
}
200210

201-
class BaseX86Register extends Pre::Instructions::X86Register { }
211+
class BaseX86Register extends Pre::Instructions::X86Register {
212+
BaseX86Register getASubRegister() { result = super.getASubRegister() }
213+
}
214+
215+
class BaseRipRegister extends BaseX86Register instanceof Pre::Instructions::RipRegister { }
216+
217+
class BaseRspRegister extends BaseX86Register instanceof Pre::Instructions::RspRegister { }
218+
219+
class BaseRbpRegister extends BaseX86Register instanceof Pre::Instructions::RbpRegister { }
220+
221+
class BaseRcxRegister extends BaseX86Register instanceof Pre::Instructions::RcxRegister { }
202222

203-
class BaseRipRegister extends BaseX86Register, Pre::Instructions::RipRegister { }
223+
class BaseRdxRegister extends BaseX86Register instanceof Pre::Instructions::RdxRegister { }
204224

205-
class BaseRspRegister extends BaseX86Register, Pre::Instructions::RspRegister { }
225+
class BaseR8Register extends BaseX86Register instanceof Pre::Instructions::R8Register { }
206226

207-
class BaseRbpRegister extends BaseX86Register, Pre::Instructions::RbpRegister { }
227+
class BaseR9Register extends BaseX86Register instanceof Pre::Instructions::R9Register { }
208228

209229
class BaseX86Operand extends Pre::Instructions::X86Operand {
210230
BaseX86Operand() { this.getUse() instanceof BaseX86Instruction }

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

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,8 @@ signature module InstructionInputSig {
1313

1414
class BaseX86Register {
1515
string toString();
16+
17+
BaseX86Register getASubRegister();
1618
}
1719

1820
class BaseRipRegister extends BaseX86Register;
@@ -21,6 +23,14 @@ signature module InstructionInputSig {
2123

2224
class BaseRbpRegister extends BaseX86Register;
2325

26+
class BaseRcxRegister extends BaseX86Register;
27+
28+
class BaseRdxRegister extends BaseX86Register;
29+
30+
class BaseR8Register extends BaseX86Register;
31+
32+
class BaseR9Register extends BaseX86Register;
33+
2434
class BaseX86RegisterAccess {
2535
string toString();
2636

@@ -122,6 +132,22 @@ module MakeInstructions<InstructionInputSig InstructionInput> {
122132

123133
class RbpRegister extends FinalRbpRegister { }
124134

135+
final private class FinalRcxRegister = BaseRcxRegister;
136+
137+
class RcxRegister extends FinalRcxRegister { }
138+
139+
final private class FinalRdxRegister = BaseRdxRegister;
140+
141+
class RdxRegister extends FinalRdxRegister { }
142+
143+
final private class FinalR8Register = BaseR8Register;
144+
145+
class R8Register extends FinalR8Register { }
146+
147+
final private class FinalR9Register = BaseR9Register;
148+
149+
class R9Register extends FinalR9Register { }
150+
125151
final private class FinalX86RegisterAccess = BaseX86RegisterAccess;
126152

127153
class X86RegisterAccess extends FinalX86RegisterAccess { }
@@ -3953,18 +3979,50 @@ private module InstructionInput0 implements InstructionInputSig {
39533979

39543980
class BaseX86Register extends @register {
39553981
string toString() { register(this, result) }
3982+
3983+
abstract BaseX86Register getASubRegister();
39563984
}
39573985

39583986
class BaseRipRegister extends BaseX86Register {
39593987
BaseRipRegister() { register(this, "rip") } // TODO: Or eip?
3988+
3989+
final override BaseX86Register getASubRegister() { register(result, "eip") }
39603990
}
39613991

39623992
class BaseRspRegister extends BaseX86Register {
39633993
BaseRspRegister() { register(this, "rsp") } // TODO: Or esp?
3994+
3995+
final override BaseX86Register getASubRegister() { register(result, "esp") }
39643996
}
39653997

39663998
class BaseRbpRegister extends BaseX86Register {
39673999
BaseRbpRegister() { register(this, "rbp") } // TODO: Or ebp?
4000+
4001+
final override BaseX86Register getASubRegister() { register(result, "rbp") }
4002+
}
4003+
4004+
class BaseRcxRegister extends BaseX86Register {
4005+
BaseRcxRegister() { register(this, "rcx") } // TODO: Or ecx?
4006+
4007+
final override BaseX86Register getASubRegister() { register(result, "ecx") }
4008+
}
4009+
4010+
class BaseRdxRegister extends BaseX86Register {
4011+
BaseRdxRegister() { register(this, "rdx") } // TODO: Or edx?
4012+
4013+
final override BaseX86Register getASubRegister() { register(result, "edx") }
4014+
}
4015+
4016+
class BaseR8Register extends BaseX86Register {
4017+
BaseR8Register() { register(this, "r8") }
4018+
4019+
final override BaseX86Register getASubRegister() { register(result, "r8d") }
4020+
}
4021+
4022+
class BaseR9Register extends BaseX86Register {
4023+
BaseR9Register() { register(this, "r9") }
4024+
4025+
final override BaseX86Register getASubRegister() { register(result, "r9d") }
39684026
}
39694027

39704028
class BaseX86RegisterAccess extends @register_access {

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

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,12 @@ module StagedConsistencyInput<InstructionSig Input> {
1515
k > 1
1616
}
1717

18+
query predicate nonUniqueOperandVariable(Input::Function f, Input::Operand op, int k) {
19+
op.getEnclosingFunction() = f and
20+
strictcount(op.getVariable()) = k and
21+
k > 1
22+
}
23+
1824
query predicate missingSuccessor(Input::Function f, Input::Instruction i) {
1925
i.getEnclosingFunction() = f and
2026
not i instanceof Input::RetInstruction and

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

Lines changed: 6 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
private import semmle.code.binary.ast.Location
22
private import Instruction
33
private import Operand
4+
private import InstructionTag
45
private import codeql.controlflow.BasicBlock as BB
56
private import codeql.util.Unit
67
private import codeql.controlflow.SuccessorType
@@ -86,15 +87,12 @@ module BinaryCfg implements BB::CfgSig<Location> {
8687

8788
ControlFlowNode getSuccessor(SuccessorType t) {
8889
t instanceof DirectSuccessor and
89-
exists(Instruction i, OperandTag tag |
90+
exists(Instruction i, OperandTag tag | this.asOperand() = i.getOperand(tag) |
91+
result.asOperand() = i.getOperand(tag.getSuccessorTag())
92+
or
9093
this.asOperand() = i.getOperand(tag) and
91-
(
92-
result.asOperand() = i.getOperand(tag.getSuccessorTag())
93-
or
94-
this.asOperand() = i.getOperand(tag) and
95-
not exists(tag.getSuccessorTag()) and
96-
result.asInstruction() = i
97-
)
94+
not exists(i.getOperand(tag.getSuccessorTag())) and
95+
result.asInstruction() = i
9896
)
9997
or
10098
exists(Instruction i | i = this.asInstruction().getSuccessor(t) |

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ class Function extends TFunction {
1414

1515
string toString() { result = this.getName() }
1616

17-
Instruction getEntryInstruction() { result = f.getEntry() }
17+
FunEntryInstruction getEntryInstruction() { result = f.getEntry() }
1818

1919
BasicBlock getEntryBlock() { result = f.getEntry().getBasicBlock() }
2020

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

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -178,6 +178,10 @@ class InstrRefInstruction extends Instruction {
178178
}
179179
}
180180

181+
class FunEntryInstruction extends Instruction {
182+
override Opcode::FunEntry opcode;
183+
}
184+
181185
class BinaryInstruction extends Instruction {
182186
override Opcode::BinaryOpcode opcode;
183187

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

Lines changed: 106 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ private import semmle.code.binary.ast.ir.internal.Opcode
33

44
newtype TInstructionTag =
55
SingleTag() or
6+
FunEntryTag() or
67
X86JumpInstrRefTag() or
78
X86JumpTag() or
89
X86CJumpInstrRefTag() or
@@ -62,6 +63,9 @@ class InstructionTag extends TInstructionTag {
6263
this = SingleTag() and
6364
result = "Single"
6465
or
66+
this = FunEntryTag() and
67+
result = "FunEntry"
68+
or
6569
this = X86JumpInstrRefTag() and
6670
result = "X86JumpInstrRef"
6771
or
@@ -209,3 +213,105 @@ class InstructionTag extends TInstructionTag {
209213
result = "CilUnconditionalBranchRef"
210214
}
211215
}
216+
217+
private newtype TOperandTag =
218+
TLeftTag() or
219+
TRightTag() or
220+
TUnaryTag() or
221+
TStoreValueTag() or
222+
TLoadAddressTag() or
223+
TStoreAddressTag() or
224+
TCallTargetTag() or
225+
TCondTag() or
226+
TCondJumpTargetTag() or
227+
TJumpTargetTag()
228+
229+
abstract class OperandTag extends TOperandTag {
230+
abstract int getIndex();
231+
232+
abstract OperandTag getSuccessorTag();
233+
234+
final OperandTag getPredecessorTag() { result.getSuccessorTag() = this }
235+
236+
abstract string toString();
237+
}
238+
239+
class LeftTag extends OperandTag, TLeftTag {
240+
final override int getIndex() { result = 0 }
241+
242+
final override OperandTag getSuccessorTag() { result instanceof RightTag }
243+
244+
final override string toString() { result = "Left" }
245+
}
246+
247+
class RightTag extends OperandTag, TRightTag {
248+
final override int getIndex() { result = 1 }
249+
250+
final override OperandTag getSuccessorTag() { none() }
251+
252+
final override string toString() { result = "Right" }
253+
}
254+
255+
class UnaryTag extends OperandTag, TUnaryTag {
256+
final override int getIndex() { result = 0 }
257+
258+
final override OperandTag getSuccessorTag() { none() }
259+
260+
final override string toString() { result = "Unary" }
261+
}
262+
263+
class StoreValueTag extends OperandTag, TStoreValueTag {
264+
final override int getIndex() { result = 1 }
265+
266+
final override OperandTag getSuccessorTag() { none() }
267+
268+
final override string toString() { result = "StoreValue" }
269+
}
270+
271+
class LoadAddressTag extends OperandTag, TLoadAddressTag {
272+
final override int getIndex() { result = 0 }
273+
274+
final override OperandTag getSuccessorTag() { none() }
275+
276+
final override string toString() { result = "LoadAddr" }
277+
}
278+
279+
class StoreAddressTag extends OperandTag, TStoreAddressTag {
280+
final override int getIndex() { result = 0 }
281+
282+
final override OperandTag getSuccessorTag() { result instanceof StoreValueTag }
283+
284+
final override string toString() { result = "StoreDest" }
285+
}
286+
287+
class CallTargetTag extends OperandTag, TCallTargetTag {
288+
final override int getIndex() { result = 0 }
289+
290+
final override OperandTag getSuccessorTag() { none() }
291+
292+
final override string toString() { result = "CallTarget" }
293+
}
294+
295+
class CondTag extends OperandTag, TCondTag {
296+
final override int getIndex() { result = 1 }
297+
298+
final override OperandTag getSuccessorTag() { none() }
299+
300+
final override string toString() { result = "CondJump" }
301+
}
302+
303+
class CondJumpTargetTag extends OperandTag, TCondJumpTargetTag {
304+
final override int getIndex() { result = 0 }
305+
306+
final override OperandTag getSuccessorTag() { result instanceof CondTag }
307+
308+
final override string toString() { result = "CondJumpTarget" }
309+
}
310+
311+
class JumpTargetTag extends OperandTag, TJumpTargetTag {
312+
final override int getIndex() { result = 0 }
313+
314+
final override OperandTag getSuccessorTag() { none() }
315+
316+
final override string toString() { result = "JumpTarget" }
317+
}

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

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
private import semmle.code.binary.ast.Location
22
private import TranslatedElement
3-
private import semmle.code.binary.ast.ir.internal.Tags
43
private import InstructionTag
54
private import Instruction
65
private import semmle.code.binary.ast.ir.internal.Opcode as Opcode
@@ -18,7 +17,7 @@ newtype TOperand =
1817
class Operand extends TOperand {
1918
TranslatedElement te;
2019
InstructionTag tag;
21-
TOperandTag operandTag;
20+
OperandTag operandTag;
2221

2322
Operand() { this = MkOperand(te, tag, operandTag) }
2423

@@ -72,7 +71,3 @@ class ConditionJumpTargetOperand extends Operand {
7271
class JumpTargetOperand extends Operand {
7372
override JumpTargetTag operandTag;
7473
}
75-
76-
private import semmle.code.binary.ast.ir.internal.Tags as Tags
77-
78-
class OperandTag = Tags::OperandTag;

0 commit comments

Comments
 (0)