8308445: Linker should check that capture state segment is big enough

Reviewed-by: mcimadamore
This commit is contained in:
Jorn Vernee 2023-06-07 12:25:28 +00:00
parent fa791119f0
commit c49129f545
4 changed files with 47 additions and 2 deletions

View file

@ -96,6 +96,7 @@ public abstract sealed class AbstractLinker implements Linker permits LinuxAArch
FunctionDescriptor fd = linkRequest.descriptor();
MethodType type = fd.toMethodType();
MethodHandle handle = arrangeDowncall(type, fd, linkRequest.options());
handle = SharedUtils.maybeCheckCaptureSegment(handle, linkRequest.options());
handle = SharedUtils.maybeInsertAllocator(fd, handle);
return handle;
});

View file

@ -78,6 +78,7 @@ public final class SharedUtils {
private static final MethodHandle MH_BUFFER_COPY;
private static final MethodHandle MH_REACHABILITY_FENCE;
public static final MethodHandle MH_CHECK_SYMBOL;
private static final MethodHandle MH_CHECK_CAPTURE_SEGMENT;
public static final AddressLayout C_POINTER = ADDRESS
.withTargetLayout(MemoryLayout.sequenceLayout(JAVA_BYTE));
@ -110,6 +111,8 @@ public final class SharedUtils {
methodType(void.class, Object.class));
MH_CHECK_SYMBOL = lookup.findStatic(SharedUtils.class, "checkSymbol",
methodType(void.class, MemorySegment.class));
MH_CHECK_CAPTURE_SEGMENT = lookup.findStatic(SharedUtils.class, "checkCaptureSegment",
methodType(MemorySegment.class, MemorySegment.class));
} catch (ReflectiveOperationException e) {
throw new BootstrapMethodError(e);
}
@ -343,6 +346,23 @@ public final class SharedUtils {
return handle;
}
public static MethodHandle maybeCheckCaptureSegment(MethodHandle handle, LinkerOptions options) {
if (options.hasCapturedCallState()) {
// (<target address>, SegmentAllocator, <capture segment>, ...) -> ...
handle = MethodHandles.filterArguments(handle, 2, MH_CHECK_CAPTURE_SEGMENT);
}
return handle;
}
@ForceInline
public static MemorySegment checkCaptureSegment(MemorySegment captureSegment) {
Objects.requireNonNull(captureSegment);
if (captureSegment.equals(MemorySegment.NULL)) {
throw new IllegalArgumentException("Capture segment is NULL: " + captureSegment);
}
return captureSegment.asSlice(0, CapturableState.LAYOUT);
}
@ForceInline
public static void checkSymbol(MemorySegment symbol) {
Objects.requireNonNull(symbol);

View file

@ -49,7 +49,6 @@ import java.util.List;
import java.util.function.Consumer;
import static java.lang.foreign.ValueLayout.ADDRESS;
import static java.lang.foreign.ValueLayout.JAVA_LONG;
import static java.lang.invoke.MethodHandles.foldArguments;
public final class FallbackLinker extends AbstractLinker {
@ -161,7 +160,7 @@ public final class FallbackLinker extends AbstractLinker {
MemorySegment capturedState = null;
if (invData.capturedStateMask() != 0) {
capturedState = (MemorySegment) args[argStart++];
capturedState = SharedUtils.checkCaptureSegment((MemorySegment) args[argStart++]);
MemorySessionImpl capturedStateImpl = ((AbstractMemorySegmentImpl) capturedState).sessionImpl();
capturedStateImpl.acquire0();
acquiredSessions.add(capturedStateImpl);