forked from oracle/graal
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
5 changed files
with
345 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
100 changes: 100 additions & 0 deletions
100
...rc/com.oracle.svm.core.windows/src/com/oracle/svm/core/windows/WindowsRegisterDumper.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,100 @@ | ||
/* | ||
* Copyright (c) 2020, 2020, Oracle and/or its affiliates. All rights reserved. | ||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. | ||
* | ||
* This code is free software; you can redistribute it and/or modify it | ||
* under the terms of the GNU General Public License version 2 only, as | ||
* published by the Free Software Foundation. Oracle designates this | ||
* particular file as subject to the "Classpath" exception as provided | ||
* by Oracle in the LICENSE file that accompanied this code. | ||
* | ||
* This code is distributed in the hope that it will be useful, but WITHOUT | ||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | ||
* version 2 for more details (a copy is included in the LICENSE file that | ||
* accompanied this code). | ||
* | ||
* You should have received a copy of the GNU General Public License version | ||
* 2 along with this work; if not, write to the Free Software Foundation, | ||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. | ||
* | ||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA | ||
* or visit www.oracle.com if you need additional information or have any | ||
* questions. | ||
*/ | ||
package com.oracle.svm.core.windows; | ||
|
||
import org.graalvm.nativeimage.ImageSingletons; | ||
import org.graalvm.nativeimage.hosted.Feature; | ||
import org.graalvm.word.PointerBase; | ||
import org.graalvm.word.WordFactory; | ||
|
||
import com.oracle.svm.core.RegisterDumper; | ||
import com.oracle.svm.core.annotate.AutomaticFeature; | ||
import com.oracle.svm.core.annotate.Uninterruptible; | ||
import com.oracle.svm.core.graal.amd64.SubstrateAMD64RegisterConfig; | ||
import com.oracle.svm.core.log.Log; | ||
import com.oracle.svm.core.util.VMError; | ||
import com.oracle.svm.core.windows.headers.ErrHandlingAPI.CONTEXT; | ||
|
||
import jdk.vm.ci.amd64.AMD64; | ||
|
||
@AutomaticFeature | ||
class WindowsRegisterDumperFeature implements Feature { | ||
@Override | ||
public void afterRegistration(AfterRegistrationAccess access) { | ||
VMError.guarantee(AMD64.r14.equals(SubstrateAMD64RegisterConfig.HEAP_BASE_REGISTER_CANDIDATE)); | ||
VMError.guarantee(AMD64.r15.equals(SubstrateAMD64RegisterConfig.THREAD_REGISTER_CANDIDATE)); | ||
ImageSingletons.add(RegisterDumper.class, new WindowsRegisterDumper()); | ||
} | ||
} | ||
|
||
public class WindowsRegisterDumper implements RegisterDumper { | ||
@Override | ||
public void dumpRegisters(Log log, Context context) { | ||
dumpRegisters(log, (CONTEXT) context); | ||
} | ||
|
||
private static void dumpRegisters(Log log, CONTEXT context) { | ||
log.string("RAX ").zhex(context.Rax()).newline(); | ||
log.string("RBX ").zhex(context.Rbx()).newline(); | ||
log.string("RCX ").zhex(context.Rcx()).newline(); | ||
log.string("RDX ").zhex(context.Rdx()).newline(); | ||
log.string("RBP ").zhex(context.Rbp()).newline(); | ||
log.string("RSI ").zhex(context.Rsi()).newline(); | ||
log.string("RDI ").zhex(context.Rdi()).newline(); | ||
log.string("RSP ").zhex(context.Rsp()).newline(); | ||
log.string("R8 ").zhex(context.R8()).newline(); | ||
log.string("R9 ").zhex(context.R9()).newline(); | ||
log.string("R10 ").zhex(context.R10()).newline(); | ||
log.string("R11 ").zhex(context.R11()).newline(); | ||
log.string("R12 ").zhex(context.R12()).newline(); | ||
log.string("R13 ").zhex(context.R13()).newline(); | ||
log.string("R14 ").zhex(context.R14()).newline(); | ||
log.string("R15 ").zhex(context.R15()).newline(); | ||
log.string("EFL ").zhex(context.EFlags()).newline(); | ||
log.string("RIP ").zhex(context.Rip()).newline(); | ||
} | ||
|
||
@Override | ||
@Uninterruptible(reason = "Called from uninterruptible code.", mayBeInlined = true) | ||
public PointerBase getHeapBase(Context context) { | ||
return WordFactory.pointer(((CONTEXT) context).R14()); | ||
} | ||
|
||
@Override | ||
@Uninterruptible(reason = "Called from uninterruptible code.", mayBeInlined = true) | ||
public PointerBase getThreadPointer(Context context) { | ||
return WordFactory.pointer(((CONTEXT) context).R15()); | ||
} | ||
|
||
@Override | ||
public PointerBase getSP(Context context) { | ||
return WordFactory.pointer(((CONTEXT) context).Rsp()); | ||
} | ||
|
||
@Override | ||
public PointerBase getIP(Context context) { | ||
return WordFactory.pointer(((CONTEXT) context).Rip()); | ||
} | ||
} |
108 changes: 108 additions & 0 deletions
108
...cle.svm.core.windows/src/com/oracle/svm/core/windows/WindowsSubstrateSegfaultHandler.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,108 @@ | ||
/* | ||
* Copyright (c) 2020, 2020, Oracle and/or its affiliates. All rights reserved. | ||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. | ||
* | ||
* This code is free software; you can redistribute it and/or modify it | ||
* under the terms of the GNU General Public License version 2 only, as | ||
* published by the Free Software Foundation. Oracle designates this | ||
* particular file as subject to the "Classpath" exception as provided | ||
* by Oracle in the LICENSE file that accompanied this code. | ||
* | ||
* This code is distributed in the hope that it will be useful, but WITHOUT | ||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | ||
* version 2 for more details (a copy is included in the LICENSE file that | ||
* accompanied this code). | ||
* | ||
* You should have received a copy of the GNU General Public License version | ||
* 2 along with this work; if not, write to the Free Software Foundation, | ||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. | ||
* | ||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA | ||
* or visit www.oracle.com if you need additional information or have any | ||
* questions. | ||
*/ | ||
package com.oracle.svm.core.windows; | ||
|
||
import static com.oracle.svm.core.annotate.RestrictHeapAccess.Access.NO_ALLOCATION; | ||
import static com.oracle.svm.core.annotate.RestrictHeapAccess.Access.NO_HEAP_ACCESS; | ||
|
||
import org.graalvm.nativeimage.ImageSingletons; | ||
import org.graalvm.nativeimage.c.function.CEntryPoint; | ||
import org.graalvm.nativeimage.c.function.CEntryPointLiteral; | ||
import org.graalvm.nativeimage.c.function.CFunctionPointer; | ||
import org.graalvm.nativeimage.hosted.Feature; | ||
|
||
import com.oracle.svm.core.SubstrateSegfaultHandler; | ||
import com.oracle.svm.core.annotate.AutomaticFeature; | ||
import com.oracle.svm.core.annotate.RestrictHeapAccess; | ||
import com.oracle.svm.core.annotate.Uninterruptible; | ||
import com.oracle.svm.core.c.function.CEntryPointOptions; | ||
import com.oracle.svm.core.c.function.CEntryPointOptions.NoEpilogue; | ||
import com.oracle.svm.core.c.function.CEntryPointOptions.NoPrologue; | ||
import com.oracle.svm.core.c.function.CEntryPointOptions.NotIncludedAutomatically; | ||
import com.oracle.svm.core.c.function.CEntryPointOptions.Publish; | ||
import com.oracle.svm.core.util.VMError; | ||
import com.oracle.svm.core.windows.headers.ErrHandlingAPI; | ||
|
||
@AutomaticFeature | ||
class WindowsSubstrateSegfaultHandlerFeature implements Feature { | ||
@Override | ||
public void afterRegistration(AfterRegistrationAccess access) { | ||
ImageSingletons.add(SubstrateSegfaultHandler.class, new WindowsSubstrateSegfaultHandler()); | ||
} | ||
} | ||
|
||
class WindowsSubstrateSegfaultHandler extends SubstrateSegfaultHandler { | ||
@Override | ||
protected void install() { | ||
/* | ||
* Normally we would use SEH (Structured Exception Handling) for this. However, in order for | ||
* SEH to work, the OS must be able to perform stack walking. On x64, this requires the | ||
* presence of unwinding info for all methods in the PE image, and we do not currently | ||
* support its generation. | ||
* | ||
* This leaves us with two options to choose from: VEH (Vectored Exception Handler) and VCH | ||
* (Vectored Continue Handler). The problem with VEHs is that they are called too early, | ||
* before any SEH processing, so we can't know if an exception will be handled, and we don't | ||
* want to interfere with the native code. | ||
* | ||
* On the other hand, VCHs are called after SEH processing, but only under certain | ||
* conditions. In fact, this implementation actually relies on the OS to call them | ||
* unconditionally due to the lack of stack-walking support. While this is obviously far | ||
* from ideal, it should be good enough for now. | ||
*/ | ||
if (ErrHandlingAPI.AddVectoredContinueHandler(0, HANDLER_LITERAL.getFunctionPointer()).isNull()) { | ||
VMError.shouldNotReachHere("SubstrateSegfaultHandler installation failed."); | ||
} | ||
} | ||
|
||
private static final CEntryPointLiteral<CFunctionPointer> HANDLER_LITERAL = CEntryPointLiteral.create(WindowsSubstrateSegfaultHandler.class, | ||
"handler", ErrHandlingAPI.EXCEPTION_POINTERS.class); | ||
|
||
@CEntryPoint | ||
@CEntryPointOptions(prologue = NoPrologue.class, epilogue = NoEpilogue.class, publishAs = Publish.SymbolOnly, include = NotIncludedAutomatically.class) | ||
@Uninterruptible(reason = "Must be uninterruptible until we get immune to safepoints.") | ||
@RestrictHeapAccess(access = NO_HEAP_ACCESS, reason = "We have yet to enter the isolate.") | ||
private static int handler(ErrHandlingAPI.EXCEPTION_POINTERS exceptionInfo) { | ||
ErrHandlingAPI.EXCEPTION_RECORD exceptionRecord = exceptionInfo.ExceptionRecord(); | ||
if (exceptionRecord.ExceptionCode() != ErrHandlingAPI.EXCEPTION_ACCESS_VIOLATION()) { | ||
/* Not a segfault. */ | ||
return ErrHandlingAPI.EXCEPTION_CONTINUE_SEARCH(); | ||
} | ||
|
||
ErrHandlingAPI.CONTEXT context = exceptionInfo.ContextRecord(); | ||
if (tryEnterIsolate(context)) { | ||
dump(context); | ||
throw shouldNotReachHere(); | ||
} | ||
/* Nothing we can do. */ | ||
return ErrHandlingAPI.EXCEPTION_CONTINUE_SEARCH(); | ||
} | ||
|
||
@Uninterruptible(reason = "Called from uninterruptible code.") | ||
@RestrictHeapAccess(access = NO_ALLOCATION, reason = "Must not allocate in segfault handler.", overridesCallers = true) | ||
private static RuntimeException shouldNotReachHere() { | ||
return VMError.shouldNotReachHere(); | ||
} | ||
} |
131 changes: 131 additions & 0 deletions
131
...c/com.oracle.svm.core.windows/src/com/oracle/svm/core/windows/headers/ErrHandlingAPI.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,131 @@ | ||
/* | ||
* Copyright (c) 2020, 2020, Oracle and/or its affiliates. All rights reserved. | ||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. | ||
* | ||
* This code is free software; you can redistribute it and/or modify it | ||
* under the terms of the GNU General Public License version 2 only, as | ||
* published by the Free Software Foundation. Oracle designates this | ||
* particular file as subject to the "Classpath" exception as provided | ||
* by Oracle in the LICENSE file that accompanied this code. | ||
* | ||
* This code is distributed in the hope that it will be useful, but WITHOUT | ||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | ||
* version 2 for more details (a copy is included in the LICENSE file that | ||
* accompanied this code). | ||
* | ||
* You should have received a copy of the GNU General Public License version | ||
* 2 along with this work; if not, write to the Free Software Foundation, | ||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. | ||
* | ||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA | ||
* or visit www.oracle.com if you need additional information or have any | ||
* questions. | ||
*/ | ||
package com.oracle.svm.core.windows.headers; | ||
|
||
import static org.graalvm.nativeimage.c.function.CFunction.Transition.NO_TRANSITION; | ||
|
||
import org.graalvm.nativeimage.c.CContext; | ||
import org.graalvm.nativeimage.c.constant.CConstant; | ||
import org.graalvm.nativeimage.c.function.CFunction; | ||
import org.graalvm.nativeimage.c.function.CFunctionPointer; | ||
import org.graalvm.nativeimage.c.struct.CField; | ||
import org.graalvm.nativeimage.c.struct.CStruct; | ||
import org.graalvm.word.PointerBase; | ||
|
||
import com.oracle.svm.core.RegisterDumper; | ||
|
||
// Checkstyle: stop | ||
|
||
/** | ||
* Definitions for Windows errhandlingapi.h | ||
*/ | ||
@CContext(WindowsDirectives.class) | ||
public class ErrHandlingAPI { | ||
|
||
/** Registers a vectored continue handler. */ | ||
@CFunction(transition = NO_TRANSITION) | ||
public static native PointerBase AddVectoredContinueHandler(int first, CFunctionPointer handler); | ||
|
||
@CConstant | ||
public static native int EXCEPTION_CONTINUE_SEARCH(); | ||
|
||
/** Contains pointers to exception and context records. */ | ||
@CStruct | ||
public interface EXCEPTION_POINTERS extends PointerBase { | ||
@CField | ||
EXCEPTION_RECORD ExceptionRecord(); | ||
|
||
@CField | ||
CONTEXT ContextRecord(); | ||
} | ||
|
||
/** Contains a description of the exception. */ | ||
@CStruct | ||
public interface EXCEPTION_RECORD extends PointerBase { | ||
@CField | ||
int ExceptionCode(); | ||
} | ||
|
||
@CConstant | ||
public static native int EXCEPTION_ACCESS_VIOLATION(); | ||
|
||
/** Contains processor-specific register data. */ | ||
@CStruct | ||
public interface CONTEXT extends RegisterDumper.Context { | ||
@CField | ||
int EFlags(); | ||
|
||
@CField | ||
long Rax(); | ||
|
||
@CField | ||
long Rcx(); | ||
|
||
@CField | ||
long Rdx(); | ||
|
||
@CField | ||
long Rbx(); | ||
|
||
@CField | ||
long Rsp(); | ||
|
||
@CField | ||
long Rbp(); | ||
|
||
@CField | ||
long Rsi(); | ||
|
||
@CField | ||
long Rdi(); | ||
|
||
@CField | ||
long R8(); | ||
|
||
@CField | ||
long R9(); | ||
|
||
@CField | ||
long R10(); | ||
|
||
@CField | ||
long R11(); | ||
|
||
@CField | ||
long R12(); | ||
|
||
@CField | ||
long R13(); | ||
|
||
@CField | ||
long R14(); | ||
|
||
@CField | ||
long R15(); | ||
|
||
@CField | ||
long Rip(); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters