Skip to content

Commit 83e1236

Browse files
committed
Extract and expose JVM method access flags
Adds extraction of raw JVM method access flags to the database and exposes them in QL via predicates for each flag. Updates the schema, extractor, and QL libraries to support querying method visibility and modifiers. Also improves error logging for constant pool extraction failures.
1 parent f66db26 commit 83e1236

5 files changed

Lines changed: 96 additions & 7 deletions

File tree

binary/extractor/jvm/Semmle.Extraction.Java.ByteCode/JvmExtractor.cs

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -139,6 +139,9 @@ private void ExtractMethod(Method method, int typeId, ClassFile classFile, strin
139139

140140
trap.WriteTuple("methods", methodId, methodName, signature, typeId);
141141

142+
// Extract access flags as raw bitmask
143+
trap.WriteTuple("jvm_method_access_flags", methodId, (int)method.AccessFlags);
144+
142145
// Check if this is a static method (for parameter indexing)
143146
bool isStatic = (method.AccessFlags & AccessFlag.Static) != 0;
144147

@@ -588,9 +591,10 @@ private void ExtractFieldRef(Instruction instr, int instrId, ClassFile classFile
588591
fieldRef.Name ?? "",
589592
fieldRef.Descriptor ?? "");
590593
}
591-
catch
594+
catch (Exception ex)
592595
{
593-
// Ignore constant pool resolution errors
596+
// Log but continue - malformed constant pool entries shouldn't stop extraction
597+
Console.Error.WriteLine($" Warning: Failed to extract field reference: {ex.Message}");
594598
}
595599
}
596600

@@ -648,9 +652,10 @@ private void ExtractMethodRef(Instruction instr, int instrId, ClassFile classFil
648652
trap.WriteTuple("jvm_call_has_return_value", instrId);
649653
}
650654
}
651-
catch
655+
catch (Exception ex)
652656
{
653-
// Ignore constant pool resolution errors
657+
// Log but continue - malformed constant pool entries shouldn't stop extraction
658+
Console.Error.WriteLine($" Warning: Failed to extract method reference: {ex.Message}");
654659
}
655660
}
656661

@@ -664,9 +669,10 @@ private void ExtractTypeRef(ConstantHandle constHandle, int instrId, ClassFile c
664669
var classConst = classFile.Constants.Get(new ClassConstantHandle(constHandle.Slot));
665670
trap.WriteTuple("jvm_type_operand", instrId, classConst.Name?.Replace('/', '.') ?? "");
666671
}
667-
catch
672+
catch (Exception ex)
668673
{
669-
// Ignore constant pool resolution errors
674+
// Log but continue - malformed constant pool entries shouldn't stop extraction
675+
Console.Error.WriteLine($" Warning: Failed to extract type reference: {ex.Message}");
670676
}
671677
}
672678

binary/extractor/jvm/semmlecode.binary.dbscheme

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2921,3 +2921,25 @@ jvm_parameter(
29212921
string name: string ref,
29222922
string descriptor: string ref
29232923
);
2924+
2925+
/**
2926+
* JVM method access flags.
2927+
* Stores the raw JVM access_flags bitmask for a method.
2928+
* See JVM spec §4.6 for flag definitions:
2929+
* 0x0001 = ACC_PUBLIC
2930+
* 0x0002 = ACC_PRIVATE
2931+
* 0x0004 = ACC_PROTECTED
2932+
* 0x0008 = ACC_STATIC
2933+
* 0x0010 = ACC_FINAL
2934+
* 0x0020 = ACC_SYNCHRONIZED
2935+
* 0x0040 = ACC_BRIDGE
2936+
* 0x0080 = ACC_VARARGS
2937+
* 0x0100 = ACC_NATIVE
2938+
* 0x0400 = ACC_ABSTRACT
2939+
* 0x0800 = ACC_STRICT
2940+
* 0x1000 = ACC_SYNTHETIC
2941+
*/
2942+
jvm_method_access_flags(
2943+
unique int method: @method ref,
2944+
int flags: int ref
2945+
);

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

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,45 @@ class JvmMethod extends @method {
8282
JvmType getDeclaringType() { methods(this, _, _, result) }
8383

8484
Location getLocation() { none() }
85+
86+
/** Gets the raw JVM access flags bitmask for this method. */
87+
int getAccessFlags() { jvm_method_access_flags(this, result) }
88+
89+
/** Holds if this method is public. */
90+
predicate isPublic() { this.getAccessFlags().bitAnd(1) != 0 }
91+
92+
/** Holds if this method is private. */
93+
predicate isPrivate() { this.getAccessFlags().bitAnd(2) != 0 }
94+
95+
/** Holds if this method is protected. */
96+
predicate isProtected() { this.getAccessFlags().bitAnd(4) != 0 }
97+
98+
/** Holds if this method is static. */
99+
predicate isStatic() { this.getAccessFlags().bitAnd(8) != 0 }
100+
101+
/** Holds if this method is final. */
102+
predicate isFinal() { this.getAccessFlags().bitAnd(16) != 0 }
103+
104+
/** Holds if this method is synchronized. */
105+
predicate isSynchronized() { this.getAccessFlags().bitAnd(32) != 0 }
106+
107+
/** Holds if this method is a bridge method. */
108+
predicate isBridge() { this.getAccessFlags().bitAnd(64) != 0 }
109+
110+
/** Holds if this method accepts variable arguments. */
111+
predicate isVarArgs() { this.getAccessFlags().bitAnd(128) != 0 }
112+
113+
/** Holds if this method is native. */
114+
predicate isNative() { this.getAccessFlags().bitAnd(256) != 0 }
115+
116+
/** Holds if this method is abstract. */
117+
predicate isAbstract() { this.getAccessFlags().bitAnd(1024) != 0 }
118+
119+
/** Holds if this method uses strict floating-point. */
120+
predicate isStrict() { this.getAccessFlags().bitAnd(2048) != 0 }
121+
122+
/** Holds if this method is synthetic (compiler-generated). */
123+
predicate isSynthetic() { this.getAccessFlags().bitAnd(4096) != 0 }
85124
}
86125

87126
pragma[nomagic]

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
@@ -322,7 +322,7 @@ class TranslatedJvmMethod extends TranslatedFunction, TTranslatedJvmMethod {
322322

323323
override predicate isProgramEntryPoint() { none() }
324324

325-
override predicate isPublic() { any() } // TODO: Extract access modifiers
325+
override predicate isPublic() { method.isPublic() }
326326

327327
override Instruction getBodyEntry() {
328328
result = this.getParameter(0).getEntry()

binary/ql/lib/semmlecode.binary.dbscheme

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2921,3 +2921,25 @@ jvm_parameter(
29212921
string name: string ref,
29222922
string descriptor: string ref
29232923
);
2924+
2925+
/**
2926+
* JVM method access flags.
2927+
* Stores the raw JVM access_flags bitmask for a method.
2928+
* See JVM spec §4.6 for flag definitions:
2929+
* 0x0001 = ACC_PUBLIC
2930+
* 0x0002 = ACC_PRIVATE
2931+
* 0x0004 = ACC_PROTECTED
2932+
* 0x0008 = ACC_STATIC
2933+
* 0x0010 = ACC_FINAL
2934+
* 0x0020 = ACC_SYNCHRONIZED
2935+
* 0x0040 = ACC_BRIDGE
2936+
* 0x0080 = ACC_VARARGS
2937+
* 0x0100 = ACC_NATIVE
2938+
* 0x0400 = ACC_ABSTRACT
2939+
* 0x0800 = ACC_STRICT
2940+
* 0x1000 = ACC_SYNTHETIC
2941+
*/
2942+
jvm_method_access_flags(
2943+
unique int method: @method ref,
2944+
int flags: int ref
2945+
);

0 commit comments

Comments
 (0)