Skip to content

Commit ce76e35

Browse files
committed
WiP
1 parent fcb6a1e commit ce76e35

File tree

5 files changed

+62
-25
lines changed

5 files changed

+62
-25
lines changed

substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/InvalidVTableEntryHandler.java renamed to substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/InvalidMethodPointerHandler.java

Lines changed: 27 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -43,33 +43,51 @@
4343
import com.oracle.svm.util.ReflectionUtil;
4444

4545
/**
46-
* Provides a stub method that can be used to fill otherwise unused vtable slots. Instead of a
47-
* segfault, this method provides a full diagnostic output with a stack trace.
46+
* Provides stub methods that can be used for uninitialized method pointers. Instead of a segfault,
47+
* the stubs provide full diagnostic output with a stack trace.
4848
*/
49-
public final class InvalidVTableEntryHandler {
50-
public static final Method HANDLER_METHOD = ReflectionUtil.lookupMethod(InvalidVTableEntryHandler.class, "invalidVTableEntryHandler");
51-
public static final String MSG = "Fatal error: Virtual method call used an illegal vtable entry that was seen as unused by the static analysis";
49+
public final class InvalidMethodPointerHandler {
50+
public static final Method INVALID_VTABLE_ENTRY_HANDLER_METHOD = ReflectionUtil.lookupMethod(InvalidMethodPointerHandler.class, "invalidVTableEntryHandler");
51+
public static final String INVALID_VTABLE_ENTRY_MSG = "Fatal error: Virtual method call used an illegal vtable entry that was seen as unused by the static analysis";
52+
53+
public static final Method METHOD_POINTER_NOT_COMPILED_HANDLER_METHOD = ReflectionUtil.lookupMethod(InvalidMethodPointerHandler.class, "methodPointerNotCompiledHandler");
54+
public static final String METHOD_POINTER_NOT_COMPILED_MSG = "Fatal error: Method pointer invoked on a method that was not registered for compilation nor seen by the static analysis";
5255

5356
@StubCallingConvention
5457
@NeverInline("We need a separate frame that stores all registers")
5558
private static void invalidVTableEntryHandler() {
5659
VMThreads.StatusSupport.setStatusIgnoreSafepoints();
5760
StackOverflowCheck.singleton().disableStackOverflowChecksForFatalError();
5861

62+
Pointer callerSP = KnownIntrinsics.readCallerStackPointer();
63+
CodePointer callerIP = KnownIntrinsics.readReturnAddress();
64+
failFatally(callerSP, callerIP, INVALID_VTABLE_ENTRY_MSG);
65+
}
66+
67+
@StubCallingConvention
68+
@NeverInline("We need a separate frame that stores all registers")
69+
private static void methodPointerNotCompiledHandler() {
70+
VMThreads.StatusSupport.setStatusIgnoreSafepoints();
71+
StackOverflowCheck.singleton().disableStackOverflowChecksForFatalError();
72+
73+
Pointer callerSP = KnownIntrinsics.readCallerStackPointer();
74+
CodePointer callerIP = KnownIntrinsics.readReturnAddress();
75+
failFatally(callerSP, callerIP, METHOD_POINTER_NOT_COMPILED_MSG);
76+
}
77+
78+
private static void failFatally(Pointer callerSP, CodePointer callerIP, String message) {
5979
/*
6080
* Since this is so far the only use case we have for a fatal error with
6181
* frameHasCalleeSavedRegisters=true, we inline the usual fatal error handling. Note that
6282
* this has the added benefit that the instructions printed as part of the crash dump are
6383
* from the method that has the illegal vtable call. That can be helpful when debugging the
6484
* cause of the fatal error.
6585
*/
66-
Pointer callerSP = KnownIntrinsics.readCallerStackPointer();
67-
CodePointer callerIP = KnownIntrinsics.readReturnAddress();
6886
LogHandler logHandler = ImageSingletons.lookup(LogHandler.class);
69-
Log log = Log.enterFatalContext(logHandler, callerIP, MSG, null);
87+
Log log = Log.enterFatalContext(logHandler, callerIP, message, null);
7088
if (log != null) {
7189
SubstrateDiagnostics.printFatalError(log, callerSP, callerIP, WordFactory.nullPointer(), true);
72-
log.string(MSG).newline();
90+
log.string(message).newline();
7391
}
7492
logHandler.fatalError();
7593
}

substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/image/NativeImageHeapWriter.java

Lines changed: 28 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -38,19 +38,24 @@
3838
import org.graalvm.nativeimage.ImageSingletons;
3939
import org.graalvm.nativeimage.c.function.CFunctionPointer;
4040
import org.graalvm.nativeimage.c.function.RelocatedPointer;
41+
import org.graalvm.nativeimage.hosted.Feature;
4142
import org.graalvm.word.WordBase;
4243

44+
import com.oracle.graal.pointsto.meta.AnalysisMethod;
4345
import com.oracle.graal.pointsto.util.AnalysisError;
4446
import com.oracle.objectfile.ObjectFile;
4547
import com.oracle.svm.core.FrameAccess;
48+
import com.oracle.svm.core.InvalidMethodPointerHandler;
4649
import com.oracle.svm.core.StaticFieldsSupport;
50+
import com.oracle.svm.core.annotate.AutomaticFeature;
4751
import com.oracle.svm.core.config.ConfigurationValues;
4852
import com.oracle.svm.core.config.ObjectLayout;
4953
import com.oracle.svm.core.heap.Heap;
5054
import com.oracle.svm.core.heap.ObjectHeader;
5155
import com.oracle.svm.core.hub.DynamicHub;
5256
import com.oracle.svm.core.image.ImageHeapLayoutInfo;
5357
import com.oracle.svm.core.meta.SubstrateObjectConstant;
58+
import com.oracle.svm.hosted.FeatureImpl;
5459
import com.oracle.svm.hosted.config.HybridLayout;
5560
import com.oracle.svm.hosted.image.NativeImageHeap.ObjectInfo;
5661
import com.oracle.svm.hosted.meta.HostedClass;
@@ -243,13 +248,14 @@ private void addNonDataRelocation(RelocatableBuffer buffer, int index, Relocated
243248
assert pointer instanceof CFunctionPointer : "unknown relocated pointer " + pointer;
244249
assert pointer instanceof MethodPointer : "cannot create relocation for unknown FunctionPointer " + pointer;
245250

251+
RelocatedPointer target = pointer;
246252
ResolvedJavaMethod method = ((MethodPointer) pointer).getMethod();
247253
HostedMethod hMethod = method instanceof HostedMethod ? (HostedMethod) method : heap.getUniverse().lookup(method);
248-
if (hMethod.isCompiled()) {
249-
// Only compiled methods inserted in vtables require relocation.
250-
int pointerSize = ConfigurationValues.getTarget().wordSize;
251-
addDirectRelocationWithoutAddend(buffer, index, pointerSize, pointer);
254+
if (!hMethod.isCompiled()) {
255+
target = ImageSingletons.lookup(MethodPointerNotCompiledHandlerFeature.class).getNotCompiledHandler();
252256
}
257+
int pointerSize = ConfigurationValues.getTarget().wordSize;
258+
addDirectRelocationWithoutAddend(buffer, index, pointerSize, target);
253259
}
254260

255261
private static void writePrimitive(RelocatableBuffer buffer, int index, JavaConstant con) {
@@ -398,3 +404,21 @@ private void writeObject(ObjectInfo info, RelocatableBuffer buffer) {
398404
}
399405
}
400406
}
407+
408+
@AutomaticFeature
409+
final class MethodPointerNotCompiledHandlerFeature implements Feature {
410+
private CFunctionPointer notCompiledHandler;
411+
412+
@Override
413+
public void beforeAnalysis(BeforeAnalysisAccess a) {
414+
FeatureImpl.BeforeAnalysisAccessImpl access = (FeatureImpl.BeforeAnalysisAccessImpl) a;
415+
AnalysisMethod notCompiledMethod = access.getMetaAccess().lookupJavaMethod(InvalidMethodPointerHandler.METHOD_POINTER_NOT_COMPILED_HANDLER_METHOD);
416+
access.registerAsCompiled(notCompiledMethod);
417+
notCompiledHandler = MethodPointer.factory(notCompiledMethod);
418+
}
419+
420+
CFunctionPointer getNotCompiledHandler() {
421+
assert notCompiledHandler != null;
422+
return notCompiledHandler;
423+
}
424+
}

substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/meta/MethodPointer.java

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,8 @@
2929
import org.graalvm.nativeimage.c.function.CFunctionPointer;
3030
import org.graalvm.word.ComparableWord;
3131

32+
import com.oracle.svm.core.util.VMError;
33+
3234
import jdk.vm.ci.meta.ResolvedJavaMethod;
3335

3436
/**
@@ -39,11 +41,8 @@ public class MethodPointer implements CFunctionPointer {
3941
private final ResolvedJavaMethod method;
4042

4143
public static CFunctionPointer factory(ResolvedJavaMethod method) {
42-
if (method == null) {
43-
return null;
44-
} else {
45-
return new MethodPointer(method);
46-
}
44+
VMError.guarantee(method != null);
45+
return new MethodPointer(method);
4746
}
4847

4948
protected MethodPointer(ResolvedJavaMethod method) {

substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/meta/UniverseBuilder.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,7 @@
6363
import com.oracle.graal.pointsto.meta.AnalysisUniverse;
6464
import com.oracle.graal.pointsto.results.AbstractAnalysisResultsBuilder;
6565
import com.oracle.svm.core.FunctionPointerHolder;
66-
import com.oracle.svm.core.InvalidVTableEntryHandler;
66+
import com.oracle.svm.core.InvalidMethodPointerHandler;
6767
import com.oracle.svm.core.StaticFieldsSupport;
6868
import com.oracle.svm.core.SubstrateOptions;
6969
import com.oracle.svm.core.SubstrateUtil;
@@ -674,7 +674,7 @@ private void buildVTables() {
674674
* To avoid segfaults when jumping to address 0, all unused vtable entries are filled with a
675675
* stub that reports a fatal error.
676676
*/
677-
HostedMethod invalidVTableEntryHandler = hMetaAccess.lookupJavaMethod(InvalidVTableEntryHandler.HANDLER_METHOD);
677+
HostedMethod invalidVTableEntryHandler = hMetaAccess.lookupJavaMethod(InvalidMethodPointerHandler.INVALID_VTABLE_ENTRY_HANDLER_METHOD);
678678

679679
for (HostedType type : hUniverse.getTypes()) {
680680
if (type.isArray()) {
@@ -999,6 +999,6 @@ final class InvalidVTableEntryFeature implements Feature {
999999
@Override
10001000
public void beforeAnalysis(BeforeAnalysisAccess a) {
10011001
BeforeAnalysisAccessImpl access = (BeforeAnalysisAccessImpl) a;
1002-
access.registerAsCompiled(InvalidVTableEntryHandler.HANDLER_METHOD);
1002+
access.registerAsCompiled(InvalidMethodPointerHandler.INVALID_VTABLE_ENTRY_HANDLER_METHOD);
10031003
}
10041004
}

substratevm/src/com.oracle.svm.jni/src/com/oracle/svm/jni/access/JNINativeLinkage.java

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -204,8 +204,4 @@ private static StringBuilder mangleName(String name, int beginIndex, int endInde
204204
}
205205
return sb;
206206
}
207-
208-
public static String mangle(String s) {
209-
return mangleName(s, 0, s.length(), new StringBuilder()).toString();
210-
}
211207
}

0 commit comments

Comments
 (0)