Skip to content

Commit 24574be

Browse files
committed
C++: add SizedBuffer side effect instructions
1 parent 554d639 commit 24574be

File tree

11 files changed

+761
-578
lines changed

11 files changed

+761
-578
lines changed

cpp/ql/src/semmle/code/cpp/ir/implementation/Opcode.qll

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,9 @@ private newtype TOpcode =
7171
TBufferReadSideEffect() or
7272
TBufferMustWriteSideEffect() or
7373
TBufferMayWriteSideEffect() or
74+
TSizedBufferReadSideEffect() or
75+
TSizedBufferMustWriteSideEffect() or
76+
TSizedBufferMayWriteSideEffect() or
7477
TChi() or
7578
TInlineAsm() or
7679
TUnreached() or
@@ -147,10 +150,16 @@ abstract class MustWriteSideEffectOpcode extends WriteSideEffectOpcode { }
147150
abstract class MayWriteSideEffectOpcode extends WriteSideEffectOpcode { }
148151

149152
/**
150-
* An opcode that accesses a buffer via an `AddressOperand` and a `BufferSizeOperand`.
153+
* An opcode that accesses a buffer via an `AddressOperand`.
151154
*/
152155
abstract class BufferAccessOpcode extends MemoryAccessOpcode { }
153156

157+
/**
158+
* An opcode that accesses a buffer via an `AddressOperand` with a `BufferSizeOperand` specifying
159+
* the number of elements accessed.
160+
*/
161+
abstract class SizedBufferAccessOpcode extends BufferAccessOpcode { }
162+
154163
module Opcode {
155164
class NoOp extends Opcode, TNoOp {
156165
final override string toString() { result = "NoOp" }
@@ -445,6 +454,21 @@ module Opcode {
445454
final override string toString() { result = "BufferMayWriteSideEffect" }
446455
}
447456

457+
class SizedBufferReadSideEffect extends ReadSideEffectOpcode, SizedBufferAccessOpcode,
458+
TSizedBufferReadSideEffect {
459+
final override string toString() { result = "SizedBufferReadSideEffect" }
460+
}
461+
462+
class SizedBufferMustWriteSideEffect extends MustWriteSideEffectOpcode, SizedBufferAccessOpcode,
463+
TSizedBufferMustWriteSideEffect {
464+
final override string toString() { result = "SizedBufferMustWriteSideEffect" }
465+
}
466+
467+
class SizedBufferMayWriteSideEffect extends MayWriteSideEffectOpcode, SizedBufferAccessOpcode,
468+
TSizedBufferMayWriteSideEffect {
469+
final override string toString() { result = "SizedBufferMayWriteSideEffect" }
470+
}
471+
448472
class Chi extends Opcode, TChi {
449473
final override string toString() { result = "Chi" }
450474
}

cpp/ql/src/semmle/code/cpp/ir/implementation/aliased_ssa/Instruction.qll

Lines changed: 47 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ module InstructionSanity {
3030
or
3131
opcode instanceof MemoryAccessOpcode and tag instanceof AddressOperandTag
3232
or
33-
opcode instanceof BufferAccessOpcode and tag instanceof BufferSizeOperand
33+
opcode instanceof SizedBufferAccessOpcode and tag instanceof BufferSizeOperandTag
3434
or
3535
opcode instanceof OpcodeWithCondition and tag instanceof ConditionOperandTag
3636
or
@@ -1176,7 +1176,7 @@ class CallReadSideEffectInstruction extends SideEffectInstruction {
11761176
class IndirectReadSideEffectInstruction extends SideEffectInstruction {
11771177
IndirectReadSideEffectInstruction() { getOpcode() instanceof Opcode::IndirectReadSideEffect }
11781178

1179-
Instruction getArgumentInstruction() { result = getAnOperand().(AddressOperand).getDef() }
1179+
Instruction getArgumentDef() { result = getAnOperand().(AddressOperand).getDef() }
11801180
}
11811181

11821182
/**
@@ -1185,7 +1185,20 @@ class IndirectReadSideEffectInstruction extends SideEffectInstruction {
11851185
class BufferReadSideEffectInstruction extends SideEffectInstruction {
11861186
BufferReadSideEffectInstruction() { getOpcode() instanceof Opcode::BufferReadSideEffect }
11871187

1188-
Instruction getArgumentInstruction() { result = getAnOperand().(AddressOperand).getDef() }
1188+
Instruction getArgumentDef() { result = getAnOperand().(AddressOperand).getDef() }
1189+
}
1190+
1191+
/**
1192+
* An instruction representing the read of an indirect buffer parameter within a function call.
1193+
*/
1194+
class SizedBufferReadSideEffectInstruction extends SideEffectInstruction {
1195+
SizedBufferReadSideEffectInstruction() {
1196+
getOpcode() instanceof Opcode::SizedBufferReadSideEffect
1197+
}
1198+
1199+
Instruction getArgumentDef() { result = getAnOperand().(AddressOperand).getDef() }
1200+
1201+
Instruction getSizeDef() { result = getAnOperand().(BufferSizeOperand).getDef() }
11891202
}
11901203

11911204
/**
@@ -1194,7 +1207,7 @@ class BufferReadSideEffectInstruction extends SideEffectInstruction {
11941207
class WriteSideEffectInstruction extends SideEffectInstruction {
11951208
WriteSideEffectInstruction() { getOpcode() instanceof WriteSideEffectOpcode }
11961209

1197-
Instruction getArgumentInstruction() { result = getAnOperand().(AddressOperand).getDef() }
1210+
Instruction getArgumentDef() { result = getAnOperand().(AddressOperand).getDef() }
11981211
}
11991212

12001213
/**
@@ -1220,6 +1233,20 @@ class BufferMustWriteSideEffectInstruction extends WriteSideEffectInstruction {
12201233
final override MemoryAccessKind getResultMemoryAccess() { result instanceof BufferMemoryAccess }
12211234
}
12221235

1236+
/**
1237+
* An instruction representing the write of an indirect buffer parameter within a function call. The
1238+
* entire buffer is overwritten.
1239+
*/
1240+
class SizedBufferMustWriteSideEffectInstruction extends WriteSideEffectInstruction {
1241+
SizedBufferMustWriteSideEffectInstruction() {
1242+
getOpcode() instanceof Opcode::SizedBufferMustWriteSideEffect
1243+
}
1244+
1245+
final override MemoryAccessKind getResultMemoryAccess() { result instanceof BufferMemoryAccess }
1246+
1247+
Instruction getSizeDef() { result = getAnOperand().(BufferSizeOperand).getDef() }
1248+
}
1249+
12231250
/**
12241251
* An instruction representing the potential write of an indirect parameter within a function call.
12251252
* Unlike `IndirectWriteSideEffectInstruction`, the ___location might not be completely overwritten.
@@ -1247,6 +1274,22 @@ class BufferMayWriteSideEffectInstruction extends WriteSideEffectInstruction {
12471274
}
12481275
}
12491276

1277+
/**
1278+
* An instruction representing the write of an indirect buffer parameter within a function call.
1279+
* Unlike `BufferWriteSideEffectInstruction`, the buffer might not be completely overwritten.
1280+
*/
1281+
class SizedBufferMayWriteSideEffectInstruction extends WriteSideEffectInstruction {
1282+
SizedBufferMayWriteSideEffectInstruction() {
1283+
getOpcode() instanceof Opcode::SizedBufferMayWriteSideEffect
1284+
}
1285+
1286+
final override MemoryAccessKind getResultMemoryAccess() {
1287+
result instanceof BufferMayMemoryAccess
1288+
}
1289+
1290+
Instruction getSizeDef() { result = getAnOperand().(BufferSizeOperand).getDef() }
1291+
}
1292+
12501293
/**
12511294
* An instruction representing a GNU or MSVC inline assembly statement.
12521295
*/

cpp/ql/src/semmle/code/cpp/ir/implementation/aliased_ssa/Operand.qll

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -254,6 +254,16 @@ class AddressOperand extends RegisterOperand {
254254
override string toString() { result = "Address" }
255255
}
256256

257+
/**
258+
* The buffer size operand of an instruction that represents a read or write of
259+
* a buffer.
260+
*/
261+
class BufferSizeOperand extends RegisterOperand {
262+
override BufferSizeOperandTag tag;
263+
264+
override string toString() { result = "BufferSize" }
265+
}
266+
257267
/**
258268
* The source value operand of an instruction that loads a value from memory (e.g. `Load`,
259269
* `ReturnValue`, `ThrowValue`).

cpp/ql/src/semmle/code/cpp/ir/implementation/internal/OperandTag.qll

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,7 @@ AddressOperandTag addressOperand() { result = TAddressOperand() }
6666
* The buffer size operand of an instruction that represents a read or write of
6767
* a buffer.
6868
*/
69-
class BufferSizeOperand extends RegisterOperandTag, TBufferSizeOperand {
69+
class BufferSizeOperandTag extends RegisterOperandTag, TBufferSizeOperand {
7070
final override string toString() { result = "BufferSize" }
7171

7272
final override int getSortOrder() { result = 1 }

cpp/ql/src/semmle/code/cpp/ir/implementation/raw/Instruction.qll

Lines changed: 47 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ module InstructionSanity {
3030
or
3131
opcode instanceof MemoryAccessOpcode and tag instanceof AddressOperandTag
3232
or
33-
opcode instanceof BufferAccessOpcode and tag instanceof BufferSizeOperand
33+
opcode instanceof SizedBufferAccessOpcode and tag instanceof BufferSizeOperandTag
3434
or
3535
opcode instanceof OpcodeWithCondition and tag instanceof ConditionOperandTag
3636
or
@@ -1176,7 +1176,7 @@ class CallReadSideEffectInstruction extends SideEffectInstruction {
11761176
class IndirectReadSideEffectInstruction extends SideEffectInstruction {
11771177
IndirectReadSideEffectInstruction() { getOpcode() instanceof Opcode::IndirectReadSideEffect }
11781178

1179-
Instruction getArgumentInstruction() { result = getAnOperand().(AddressOperand).getDef() }
1179+
Instruction getArgumentDef() { result = getAnOperand().(AddressOperand).getDef() }
11801180
}
11811181

11821182
/**
@@ -1185,7 +1185,20 @@ class IndirectReadSideEffectInstruction extends SideEffectInstruction {
11851185
class BufferReadSideEffectInstruction extends SideEffectInstruction {
11861186
BufferReadSideEffectInstruction() { getOpcode() instanceof Opcode::BufferReadSideEffect }
11871187

1188-
Instruction getArgumentInstruction() { result = getAnOperand().(AddressOperand).getDef() }
1188+
Instruction getArgumentDef() { result = getAnOperand().(AddressOperand).getDef() }
1189+
}
1190+
1191+
/**
1192+
* An instruction representing the read of an indirect buffer parameter within a function call.
1193+
*/
1194+
class SizedBufferReadSideEffectInstruction extends SideEffectInstruction {
1195+
SizedBufferReadSideEffectInstruction() {
1196+
getOpcode() instanceof Opcode::SizedBufferReadSideEffect
1197+
}
1198+
1199+
Instruction getArgumentDef() { result = getAnOperand().(AddressOperand).getDef() }
1200+
1201+
Instruction getSizeDef() { result = getAnOperand().(BufferSizeOperand).getDef() }
11891202
}
11901203

11911204
/**
@@ -1194,7 +1207,7 @@ class BufferReadSideEffectInstruction extends SideEffectInstruction {
11941207
class WriteSideEffectInstruction extends SideEffectInstruction {
11951208
WriteSideEffectInstruction() { getOpcode() instanceof WriteSideEffectOpcode }
11961209

1197-
Instruction getArgumentInstruction() { result = getAnOperand().(AddressOperand).getDef() }
1210+
Instruction getArgumentDef() { result = getAnOperand().(AddressOperand).getDef() }
11981211
}
11991212

12001213
/**
@@ -1220,6 +1233,20 @@ class BufferMustWriteSideEffectInstruction extends WriteSideEffectInstruction {
12201233
final override MemoryAccessKind getResultMemoryAccess() { result instanceof BufferMemoryAccess }
12211234
}
12221235

1236+
/**
1237+
* An instruction representing the write of an indirect buffer parameter within a function call. The
1238+
* entire buffer is overwritten.
1239+
*/
1240+
class SizedBufferMustWriteSideEffectInstruction extends WriteSideEffectInstruction {
1241+
SizedBufferMustWriteSideEffectInstruction() {
1242+
getOpcode() instanceof Opcode::SizedBufferMustWriteSideEffect
1243+
}
1244+
1245+
final override MemoryAccessKind getResultMemoryAccess() { result instanceof BufferMemoryAccess }
1246+
1247+
Instruction getSizeDef() { result = getAnOperand().(BufferSizeOperand).getDef() }
1248+
}
1249+
12231250
/**
12241251
* An instruction representing the potential write of an indirect parameter within a function call.
12251252
* Unlike `IndirectWriteSideEffectInstruction`, the ___location might not be completely overwritten.
@@ -1247,6 +1274,22 @@ class BufferMayWriteSideEffectInstruction extends WriteSideEffectInstruction {
12471274
}
12481275
}
12491276

1277+
/**
1278+
* An instruction representing the write of an indirect buffer parameter within a function call.
1279+
* Unlike `BufferWriteSideEffectInstruction`, the buffer might not be completely overwritten.
1280+
*/
1281+
class SizedBufferMayWriteSideEffectInstruction extends WriteSideEffectInstruction {
1282+
SizedBufferMayWriteSideEffectInstruction() {
1283+
getOpcode() instanceof Opcode::SizedBufferMayWriteSideEffect
1284+
}
1285+
1286+
final override MemoryAccessKind getResultMemoryAccess() {
1287+
result instanceof BufferMayMemoryAccess
1288+
}
1289+
1290+
Instruction getSizeDef() { result = getAnOperand().(BufferSizeOperand).getDef() }
1291+
}
1292+
12501293
/**
12511294
* An instruction representing a GNU or MSVC inline assembly statement.
12521295
*/

cpp/ql/src/semmle/code/cpp/ir/implementation/raw/Operand.qll

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -254,6 +254,16 @@ class AddressOperand extends RegisterOperand {
254254
override string toString() { result = "Address" }
255255
}
256256

257+
/**
258+
* The buffer size operand of an instruction that represents a read or write of
259+
* a buffer.
260+
*/
261+
class BufferSizeOperand extends RegisterOperand {
262+
override BufferSizeOperandTag tag;
263+
264+
override string toString() { result = "BufferSize" }
265+
}
266+
257267
/**
258268
* The source value operand of an instruction that loads a value from memory (e.g. `Load`,
259269
* `ReturnValue`, `ThrowValue`).

cpp/ql/src/semmle/code/cpp/ir/implementation/unaliased_ssa/Instruction.qll

Lines changed: 47 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ module InstructionSanity {
3030
or
3131
opcode instanceof MemoryAccessOpcode and tag instanceof AddressOperandTag
3232
or
33-
opcode instanceof BufferAccessOpcode and tag instanceof BufferSizeOperand
33+
opcode instanceof SizedBufferAccessOpcode and tag instanceof BufferSizeOperandTag
3434
or
3535
opcode instanceof OpcodeWithCondition and tag instanceof ConditionOperandTag
3636
or
@@ -1176,7 +1176,7 @@ class CallReadSideEffectInstruction extends SideEffectInstruction {
11761176
class IndirectReadSideEffectInstruction extends SideEffectInstruction {
11771177
IndirectReadSideEffectInstruction() { getOpcode() instanceof Opcode::IndirectReadSideEffect }
11781178

1179-
Instruction getArgumentInstruction() { result = getAnOperand().(AddressOperand).getDef() }
1179+
Instruction getArgumentDef() { result = getAnOperand().(AddressOperand).getDef() }
11801180
}
11811181

11821182
/**
@@ -1185,7 +1185,20 @@ class IndirectReadSideEffectInstruction extends SideEffectInstruction {
11851185
class BufferReadSideEffectInstruction extends SideEffectInstruction {
11861186
BufferReadSideEffectInstruction() { getOpcode() instanceof Opcode::BufferReadSideEffect }
11871187

1188-
Instruction getArgumentInstruction() { result = getAnOperand().(AddressOperand).getDef() }
1188+
Instruction getArgumentDef() { result = getAnOperand().(AddressOperand).getDef() }
1189+
}
1190+
1191+
/**
1192+
* An instruction representing the read of an indirect buffer parameter within a function call.
1193+
*/
1194+
class SizedBufferReadSideEffectInstruction extends SideEffectInstruction {
1195+
SizedBufferReadSideEffectInstruction() {
1196+
getOpcode() instanceof Opcode::SizedBufferReadSideEffect
1197+
}
1198+
1199+
Instruction getArgumentDef() { result = getAnOperand().(AddressOperand).getDef() }
1200+
1201+
Instruction getSizeDef() { result = getAnOperand().(BufferSizeOperand).getDef() }
11891202
}
11901203

11911204
/**
@@ -1194,7 +1207,7 @@ class BufferReadSideEffectInstruction extends SideEffectInstruction {
11941207
class WriteSideEffectInstruction extends SideEffectInstruction {
11951208
WriteSideEffectInstruction() { getOpcode() instanceof WriteSideEffectOpcode }
11961209

1197-
Instruction getArgumentInstruction() { result = getAnOperand().(AddressOperand).getDef() }
1210+
Instruction getArgumentDef() { result = getAnOperand().(AddressOperand).getDef() }
11981211
}
11991212

12001213
/**
@@ -1220,6 +1233,20 @@ class BufferMustWriteSideEffectInstruction extends WriteSideEffectInstruction {
12201233
final override MemoryAccessKind getResultMemoryAccess() { result instanceof BufferMemoryAccess }
12211234
}
12221235

1236+
/**
1237+
* An instruction representing the write of an indirect buffer parameter within a function call. The
1238+
* entire buffer is overwritten.
1239+
*/
1240+
class SizedBufferMustWriteSideEffectInstruction extends WriteSideEffectInstruction {
1241+
SizedBufferMustWriteSideEffectInstruction() {
1242+
getOpcode() instanceof Opcode::SizedBufferMustWriteSideEffect
1243+
}
1244+
1245+
final override MemoryAccessKind getResultMemoryAccess() { result instanceof BufferMemoryAccess }
1246+
1247+
Instruction getSizeDef() { result = getAnOperand().(BufferSizeOperand).getDef() }
1248+
}
1249+
12231250
/**
12241251
* An instruction representing the potential write of an indirect parameter within a function call.
12251252
* Unlike `IndirectWriteSideEffectInstruction`, the ___location might not be completely overwritten.
@@ -1247,6 +1274,22 @@ class BufferMayWriteSideEffectInstruction extends WriteSideEffectInstruction {
12471274
}
12481275
}
12491276

1277+
/**
1278+
* An instruction representing the write of an indirect buffer parameter within a function call.
1279+
* Unlike `BufferWriteSideEffectInstruction`, the buffer might not be completely overwritten.
1280+
*/
1281+
class SizedBufferMayWriteSideEffectInstruction extends WriteSideEffectInstruction {
1282+
SizedBufferMayWriteSideEffectInstruction() {
1283+
getOpcode() instanceof Opcode::SizedBufferMayWriteSideEffect
1284+
}
1285+
1286+
final override MemoryAccessKind getResultMemoryAccess() {
1287+
result instanceof BufferMayMemoryAccess
1288+
}
1289+
1290+
Instruction getSizeDef() { result = getAnOperand().(BufferSizeOperand).getDef() }
1291+
}
1292+
12501293
/**
12511294
* An instruction representing a GNU or MSVC inline assembly statement.
12521295
*/

cpp/ql/src/semmle/code/cpp/ir/implementation/unaliased_ssa/Operand.qll

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -254,6 +254,16 @@ class AddressOperand extends RegisterOperand {
254254
override string toString() { result = "Address" }
255255
}
256256

257+
/**
258+
* The buffer size operand of an instruction that represents a read or write of
259+
* a buffer.
260+
*/
261+
class BufferSizeOperand extends RegisterOperand {
262+
override BufferSizeOperandTag tag;
263+
264+
override string toString() { result = "BufferSize" }
265+
}
266+
257267
/**
258268
* The source value operand of an instruction that loads a value from memory (e.g. `Load`,
259269
* `ReturnValue`, `ThrowValue`).

0 commit comments

Comments
 (0)