Skip to content

Commit 13f79e6

Browse files
committed
Extract and expose CIL method access flags
Adds extraction of ECMA-335 MethodAttributes flags for CIL methods and stores them in a new 'cil_method_access_flags' table. Updates QL libraries to expose these flags and predicates for common access modifiers (public, private, protected, internal, static, final, virtual, abstract). Also updates TranslatedCilMethod to use the new isPublic predicate.
1 parent 83e1236 commit 13f79e6

5 files changed

Lines changed: 101 additions & 1 deletion

File tree

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

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -108,6 +108,9 @@ private void ExtractMethod(MethodDefinition method, int typeId) {
108108
var signature = GetMethodSignature(method);
109109
trap.WriteTuple("methods", methodId, method.Name, signature, typeId);
110110

111+
// Write access flags
112+
trap.WriteTuple("cil_method_access_flags", methodId, (int)method.Attributes);
113+
111114
if (method.HasBody) {
112115
ExtractMethodBody(method, methodId);
113116
}

binary/extractor/jvm/semmlecode.binary.dbscheme

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2141,6 +2141,29 @@ methods(
21412141
int type_id: @type ref
21422142
);
21432143

2144+
/**
2145+
* CIL method access flags.
2146+
* Stores the method attributes as a bitmask.
2147+
* See ECMA-335 §II.23.1.10 for flag definitions:
2148+
* 0x0001 = MemberAccessMask (use with mask)
2149+
* 0x0006 = Public
2150+
* 0x0001 = Private
2151+
* 0x0003 = Family (protected)
2152+
* 0x0005 = FamORAssem (protected internal)
2153+
* 0x0010 = Static
2154+
* 0x0020 = Final (sealed)
2155+
* 0x0040 = Virtual
2156+
* 0x0080 = HideBySig
2157+
* 0x0100 = VtableLayoutMask (use with mask)
2158+
* 0x0400 = Abstract
2159+
* 0x0800 = SpecialName
2160+
* 0x2000 = PInvokeImpl
2161+
*/
2162+
cil_method_access_flags(
2163+
unique int method: @method ref,
2164+
int flags: int ref
2165+
);
2166+
21442167
fields(
21452168
unique int id: @field,
21462169
string name: string ref,

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

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,57 @@ class CilMethod extends @method {
7171
this.getSignature().matches("Void%") // TODO: Don't use string parsing here
7272
}
7373

74+
/** Gets the raw ECMA-335 MethodAttributes flags for this method. */
75+
int getAccessFlags() { cil_method_access_flags(this, result) }
76+
77+
/** Holds if this method is public. */
78+
predicate isPublic() {
79+
// MemberAccessMask is 0x0007, Public is 0x0006
80+
this.getAccessFlags().bitAnd(7) = 6
81+
}
82+
83+
/** Holds if this method is private. */
84+
predicate isPrivate() {
85+
// Private is 0x0001
86+
this.getAccessFlags().bitAnd(7) = 1
87+
}
88+
89+
/** Holds if this method is protected (family). */
90+
predicate isProtected() {
91+
// Family is 0x0004
92+
this.getAccessFlags().bitAnd(7) = 4
93+
}
94+
95+
/** Holds if this method is internal (assembly). */
96+
predicate isInternal() {
97+
// Assembly is 0x0003
98+
this.getAccessFlags().bitAnd(7) = 3
99+
}
100+
101+
/** Holds if this method is static. */
102+
predicate isStatic() {
103+
// Static is 0x0010
104+
this.getAccessFlags().bitAnd(16) != 0
105+
}
106+
107+
/** Holds if this method is final (sealed). */
108+
predicate isFinal() {
109+
// Final is 0x0020
110+
this.getAccessFlags().bitAnd(32) != 0
111+
}
112+
113+
/** Holds if this method is virtual. */
114+
predicate isVirtual() {
115+
// Virtual is 0x0040
116+
this.getAccessFlags().bitAnd(64) != 0
117+
}
118+
119+
/** Holds if this method is abstract. */
120+
predicate isAbstract() {
121+
// Abstract is 0x0400
122+
this.getAccessFlags().bitAnd(1024) != 0
123+
}
124+
74125
CilInstruction getAnInstruction() { il_instruction_method(result, this) }
75126

76127
CilInstruction getInstruction(int i) { il_instruction_parent(result, i, this) }

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -217,7 +217,7 @@ class TranslatedCilMethod extends TranslatedFunction, TTranslatedCilMethod {
217217

218218
override predicate isProgramEntryPoint() { none() }
219219

220-
override predicate isPublic() { any() } // TODO: We need to extract this
220+
override predicate isPublic() { method.isPublic() }
221221

222222
override Instruction getBodyEntry() {
223223
result = this.getParameter(0).getEntry()

binary/ql/lib/semmlecode.binary.dbscheme

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2141,6 +2141,29 @@ methods(
21412141
int type_id: @type ref
21422142
);
21432143

2144+
/**
2145+
* CIL method access flags.
2146+
* Stores the method attributes as a bitmask.
2147+
* See ECMA-335 §II.23.1.10 for flag definitions:
2148+
* 0x0001 = MemberAccessMask (use with mask)
2149+
* 0x0006 = Public
2150+
* 0x0001 = Private
2151+
* 0x0003 = Family (protected)
2152+
* 0x0005 = FamORAssem (protected internal)
2153+
* 0x0010 = Static
2154+
* 0x0020 = Final (sealed)
2155+
* 0x0040 = Virtual
2156+
* 0x0080 = HideBySig
2157+
* 0x0100 = VtableLayoutMask (use with mask)
2158+
* 0x0400 = Abstract
2159+
* 0x0800 = SpecialName
2160+
* 0x2000 = PInvokeImpl
2161+
*/
2162+
cil_method_access_flags(
2163+
unique int method: @method ref,
2164+
int flags: int ref
2165+
);
2166+
21442167
fields(
21452168
unique int id: @field,
21462169
string name: string ref,

0 commit comments

Comments
 (0)