Skip to content

Commit

Permalink
pageSize fix for some JDK versions and implement getCallerClass(depth)
Browse files Browse the repository at this point in the history
  • Loading branch information
xxDark committed May 19, 2022
1 parent 61ee405 commit e2f6c5c
Show file tree
Hide file tree
Showing 3 changed files with 61 additions and 26 deletions.
34 changes: 22 additions & 12 deletions src/main/java/dev/xdark/ssvm/natives/ReflectionNatives.java
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package dev.xdark.ssvm.natives;

import dev.xdark.ssvm.VirtualMachine;
import dev.xdark.ssvm.api.MethodInvoker;
import dev.xdark.ssvm.api.VMInterface;
import dev.xdark.ssvm.asm.Modifier;
import dev.xdark.ssvm.execution.ExecutionContext;
Expand Down Expand Up @@ -35,31 +36,40 @@ public void init(VirtualMachine vm) {
throw new IllegalStateException("Unable to locate Reflection class");
}
}
vmi.setInvoker(reflection, "getCallerClass", "()Ljava/lang/Class;", ctx -> {
vmi.setInvoker(reflection, "getCallerClass", "()Ljava/lang/Class;", getCallerClass(false));
vmi.setInvoker(reflection, "getCallerClass", "(I)Ljava/lang/Class;", getCallerClass(true));
vmi.setInvoker(reflection, "getClassAccessFlags", "(Ljava/lang/Class;)I", ctx -> {
JavaClass klass = ctx.getLocals().<JavaValue<JavaClass>>load(0).getValue();
ctx.setResult(IntValue.of(Modifier.eraseClass(klass.getModifiers())));
return Result.ABORT;
});
}

private static MethodInvoker getCallerClass(boolean useDepth) {
return ctx -> {
VirtualMachine vm = ctx.getVM();
Backtrace backtrace = vm.currentThread().getBacktrace();
int count = backtrace.count();
JavaMethod caller = backtrace.get(count - 2).getExecutionContext().getMethod();
int offset = 3;
int callerOffset = useDepth ? ctx.getLocals().load(0).asInt() + 1 : 2;
JavaMethod caller = backtrace.get(count - callerOffset).getExecutionContext().getMethod();
if (!useDepth) {
callerOffset++;
}
if (caller.isCallerSensitive()) {
while (true) {
StackFrame frame = backtrace.get(count - offset);
StackFrame frame = backtrace.get(count - callerOffset);
ExecutionContext frameCtx = frame.getExecutionContext();
if (frameCtx == null) break;
JavaMethod method = frameCtx.getMethod();
if (Modifier.isCallerSensitive(method.getAccess())) {
offset++;
callerOffset++;
} else {
break;
}
}
}
ctx.setResult(backtrace.get(count - offset).getDeclaringClass().getOop());
ctx.setResult(backtrace.get(count - callerOffset).getDeclaringClass().getOop());
return Result.ABORT;
});
vmi.setInvoker(reflection, "getClassAccessFlags", "(Ljava/lang/Class;)I", ctx -> {
JavaClass klass = ctx.getLocals().<JavaValue<JavaClass>>load(0).getValue();
ctx.setResult(IntValue.of(Modifier.eraseClass(klass.getModifiers())));
return Result.ABORT;
});
};
}
}
21 changes: 7 additions & 14 deletions src/main/java/dev/xdark/ssvm/natives/UnsafeNatives.java
Original file line number Diff line number Diff line change
Expand Up @@ -366,10 +366,15 @@ private static void init(VirtualMachine vm, InstanceJavaClass unsafe, UnsafeHelp
ctx.setResult(value instanceof InstanceJavaClass && ((InstanceJavaClass) value).shouldBeInitialized() ? IntValue.ONE : IntValue.ZERO);
return Result.ABORT;
});
vmi.setInvoker(unsafe, uhelper.pageSize(), "()I", ctx -> {
MethodInvoker pageSize = ctx -> {
ctx.setResult(IntValue.of(vm.getMemoryManager().pageSize()));
return Result.ABORT;
});
};
for (String str : new String[] {"pageSize0", "pageSize"}) {
if (vmi.setInvoker(unsafe, str, "()I", pageSize)) {
break;
}
}
vmi.setInvoker(unsafe, "getLongVolatile", "(Ljava/lang/Object;J)J", ctx -> {
Locals locals = ctx.getLocals();
MemoryManager memoryManager = vm.getMemoryManager();
Expand Down Expand Up @@ -621,8 +626,6 @@ private interface UnsafeHelper {

String shouldBeInitialized();

String pageSize();

String compareAndSetObject();

String copyMemory();
Expand Down Expand Up @@ -705,11 +708,6 @@ public String shouldBeInitialized() {
return "shouldBeInitialized";
}

@Override
public String pageSize() {
return "pageSize";
}

@Override
public String compareAndSetObject() {
return null; // No method for JDK 8
Expand Down Expand Up @@ -798,11 +796,6 @@ public String shouldBeInitialized() {
return "shouldBeInitialized0";
}

@Override
public String pageSize() {
return "pageSize0";
}

@Override
public String compareAndSetObject() {
return "compareAndSetObject";
Expand Down
32 changes: 32 additions & 0 deletions src/test/java/dev/xdark/ssvm/enhanced/CallerTest.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
package dev.xdark.ssvm.enhanced;

import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.condition.EnabledOnJre;
import org.junit.jupiter.api.condition.JRE;
import sun.reflect.Reflection;

@EnabledOnJre(JRE.JAVA_8)
public class CallerTest {

@Test
public void doTest() {
TestUtil.test(CallerTest.class, true);
}

@VMTest
private static void callerTest() {
if (Reflection.getCallerClass(0) != Reflection.class) {
throw new IllegalStateException();
}
if (Reflection.getCallerClass(1) != CallerTest.class) {
throw new IllegalStateException();
}
callerTestInner();
}

private static void callerTestInner() {
if (Reflection.getCallerClass() != CallerTest.class) {
throw new IllegalStateException();
}
}
}

0 comments on commit e2f6c5c

Please sign in to comment.