Skip to content

Commit baa88a8

Browse files
[GR-52613] Improve a code installation error message.
1 parent de0832d commit baa88a8

File tree

5 files changed

+24
-58
lines changed

5 files changed

+24
-58
lines changed

substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/code/AbstractRuntimeCodeInstaller.java

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -47,13 +47,11 @@ protected Pointer allocateCodeMemory(long size) {
4747
}
4848

4949
protected void makeCodeMemoryExecutableReadOnly(Pointer start, UnsignedWord size) {
50-
int result = RuntimeCodeInfoAccess.makeCodeMemoryExecutableReadOnly((CodePointer) start, size);
51-
VMError.guarantee(result == 0, "Failed to make code memory read only.");
50+
RuntimeCodeInfoAccess.makeCodeMemoryExecutableReadOnly((CodePointer) start, size);
5251
}
5352

5453
protected void makeCodeMemoryExecutableWritable(Pointer start, UnsignedWord size) {
55-
int result = RuntimeCodeInfoAccess.makeCodeMemoryExecutableWritable((CodePointer) start, size);
56-
VMError.guarantee(result == 0, "Failed to make code memory writable.");
54+
RuntimeCodeInfoAccess.makeCodeMemoryExecutableWritable((CodePointer) start, size);
5755
}
5856

5957
protected static void doInstallPrepared(SharedMethod method, CodeInfo codeInfo, SubstrateInstalledCode installedCode) {

substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/code/RuntimeCodeInfoAccess.java

Lines changed: 16 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -24,8 +24,6 @@
2424
*/
2525
package com.oracle.svm.core.code;
2626

27-
import java.util.EnumSet;
28-
2927
import org.graalvm.nativeimage.ImageSingletons;
3028
import org.graalvm.nativeimage.UnmanagedMemory;
3129
import org.graalvm.nativeimage.c.function.CodePointer;
@@ -46,6 +44,7 @@
4644
import com.oracle.svm.core.heap.Heap;
4745
import com.oracle.svm.core.heap.ObjectReferenceVisitor;
4846
import com.oracle.svm.core.os.CommittedMemoryProvider;
47+
import com.oracle.svm.core.os.VirtualMemoryProvider;
4948
import com.oracle.svm.core.util.DuplicatedInNativeCode;
5049
import com.oracle.svm.core.util.VMError;
5150

@@ -235,12 +234,23 @@ private static void releaseCodeMemory(CodePointer codeStart, UnsignedWord codeSi
235234
CommittedMemoryProvider.get().freeExecutableMemory(codeStart, codeSize, WordFactory.unsigned(SubstrateOptions.codeAlignment()));
236235
}
237236

238-
public static int makeCodeMemoryExecutableReadOnly(CodePointer codeStart, UnsignedWord codeSize) {
239-
return CommittedMemoryProvider.get().protect(codeStart, codeSize, EnumSet.of(CommittedMemoryProvider.Access.READ, CommittedMemoryProvider.Access.EXECUTE));
237+
public static void makeCodeMemoryExecutableReadOnly(CodePointer codeStart, UnsignedWord codeSize) {
238+
protectCodeMemory(codeStart, codeSize, VirtualMemoryProvider.Access.READ | VirtualMemoryProvider.Access.EXECUTE);
239+
}
240+
241+
public static void makeCodeMemoryExecutableWritable(CodePointer start, UnsignedWord size) {
242+
VMError.guarantee(RuntimeCodeCache.Options.WriteableCodeCache.getValue(), "memory must not be writable and executable at the same time unless we have a writable code cache");
243+
protectCodeMemory(start, size, VirtualMemoryProvider.Access.READ | VirtualMemoryProvider.Access.WRITE | VirtualMemoryProvider.Access.EXECUTE);
240244
}
241245

242-
public static int makeCodeMemoryExecutableWritable(CodePointer start, UnsignedWord size) {
243-
return CommittedMemoryProvider.get().protect(start, size, EnumSet.of(CommittedMemoryProvider.Access.READ, CommittedMemoryProvider.Access.WRITE, CommittedMemoryProvider.Access.EXECUTE));
246+
private static void protectCodeMemory(CodePointer codeStart, UnsignedWord codeSize, int permissions) {
247+
int result = VirtualMemoryProvider.get().protect(codeStart, codeSize, permissions);
248+
if (result != 0) {
249+
throw VMError.shouldNotReachHere("Failed to modify protection of code memory. This may be caused by " +
250+
"a. a too restrictive OS-limit of allowed memory mappings (see vm.max_map_count on Linux), " +
251+
"b. a too strict security policy if you are running on Security-Enhanced Linux (SELinux), or " +
252+
"c. a Native Image internal error.");
253+
}
244254
}
245255

246256
@Uninterruptible(reason = "Called from uninterruptible code.", mayBeInlined = true)

substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/os/AbstractCommittedMemoryProvider.java

Lines changed: 0 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -30,8 +30,6 @@
3030
import static com.oracle.svm.core.Isolates.IMAGE_HEAP_WRITABLE_END;
3131
import static org.graalvm.word.WordFactory.nullPointer;
3232

33-
import java.util.EnumSet;
34-
3533
import jdk.graal.compiler.api.replacements.Fold;
3634
import org.graalvm.word.Pointer;
3735
import org.graalvm.word.PointerBase;
@@ -41,11 +39,9 @@
4139
import com.oracle.svm.core.SubstrateOptions;
4240
import com.oracle.svm.core.Uninterruptible;
4341
import com.oracle.svm.core.c.function.CEntryPointErrors;
44-
import com.oracle.svm.core.code.RuntimeCodeCache;
4542
import com.oracle.svm.core.config.ConfigurationValues;
4643
import com.oracle.svm.core.heap.Heap;
4744
import com.oracle.svm.core.util.UnsignedUtils;
48-
import com.oracle.svm.core.util.VMError;
4945

5046
public abstract class AbstractCommittedMemoryProvider implements CommittedMemoryProvider {
5147
@Fold
@@ -85,24 +81,6 @@ protected static int protectSingleIsolateImageHeap() {
8581
return CEntryPointErrors.NO_ERROR;
8682
}
8783

88-
@Override
89-
public int protect(PointerBase start, UnsignedWord nbytes, EnumSet<Access> accessFlags) {
90-
int vmAccessBits = VirtualMemoryProvider.Access.NONE;
91-
if (accessFlags.contains(CommittedMemoryProvider.Access.READ)) {
92-
vmAccessBits |= VirtualMemoryProvider.Access.READ;
93-
}
94-
if (accessFlags.contains(CommittedMemoryProvider.Access.WRITE)) {
95-
vmAccessBits |= VirtualMemoryProvider.Access.WRITE;
96-
}
97-
if (accessFlags.contains(CommittedMemoryProvider.Access.EXECUTE)) {
98-
if ((vmAccessBits & VirtualMemoryProvider.Access.WRITE) != 0 && !RuntimeCodeCache.Options.WriteableCodeCache.getValue()) {
99-
throw VMError.shouldNotReachHere("memory should never be writable and executable at the same time");
100-
}
101-
vmAccessBits |= VirtualMemoryProvider.Access.EXECUTE;
102-
}
103-
return VirtualMemoryProvider.get().protect(start, nbytes, vmAccessBits);
104-
}
105-
10684
@Override
10785
@Uninterruptible(reason = "Called from uninterruptible code.", mayBeInlined = true)
10886
public Pointer allocateAlignedChunk(UnsignedWord nbytes, UnsignedWord alignment) {

substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/os/CommittedMemoryProvider.java

Lines changed: 2 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -24,9 +24,6 @@
2424
*/
2525
package com.oracle.svm.core.os;
2626

27-
import java.util.EnumSet;
28-
29-
import jdk.graal.compiler.api.replacements.Fold;
3027
import org.graalvm.nativeimage.ImageSingletons;
3128
import org.graalvm.nativeimage.c.type.WordPointer;
3229
import org.graalvm.word.Pointer;
@@ -37,6 +34,8 @@
3734
import com.oracle.svm.core.c.function.CEntryPointCreateIsolateParameters;
3835
import com.oracle.svm.core.heap.Heap;
3936

37+
import jdk.graal.compiler.api.replacements.Fold;
38+
4039
/**
4140
* A provider of ranges of committed memory, which is virtual memory that is backed by physical
4241
* memory or swap space.
@@ -117,23 +116,4 @@ default void beforeGarbageCollection() {
117116
*/
118117
default void afterGarbageCollection() {
119118
}
120-
121-
enum Access {
122-
READ,
123-
WRITE,
124-
EXECUTE
125-
}
126-
127-
/**
128-
* Change access permissions for a block of committed memory that was allocated with one of the
129-
* allocation methods.
130-
*
131-
* @param start The start of the address range to be protected, which must be a multiple of the
132-
* {@linkplain #getGranularity() granularity}.
133-
* @param nbytes The size in bytes of the address range to be protected, which will be rounded
134-
* up to a multiple of the {@linkplain #getGranularity() granularity}.
135-
* @param access The modes in which the memory is permitted to be accessed, see {@link Access}.
136-
* @return 0 when successful, or a non-zero implementation-specific error code.
137-
*/
138-
int protect(PointerBase start, UnsignedWord nbytes, EnumSet<Access> access);
139119
}

substratevm/src/com.oracle.svm.graal/src/com/oracle/svm/graal/isolated/IsolatedRuntimeCodeInstaller.java

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -162,8 +162,8 @@ protected void makeCodeMemoryExecutableReadOnly(Pointer start, UnsignedWord size
162162
}
163163

164164
@CEntryPoint(include = CEntryPoint.NotIncludedAutomatically.class, publishAs = CEntryPoint.Publish.NotPublished)
165-
private static int makeCodeMemoryExecutableReadOnly0(@SuppressWarnings("unused") IsolateThread targetIsolate, Pointer start, UnsignedWord size) {
166-
return RuntimeCodeInfoAccess.makeCodeMemoryExecutableReadOnly((CodePointer) start, size);
165+
private static void makeCodeMemoryExecutableReadOnly0(@SuppressWarnings("unused") IsolateThread targetIsolate, Pointer start, UnsignedWord size) {
166+
RuntimeCodeInfoAccess.makeCodeMemoryExecutableReadOnly((CodePointer) start, size);
167167
}
168168

169169
@Override
@@ -172,7 +172,7 @@ protected void makeCodeMemoryExecutableWritable(Pointer start, UnsignedWord size
172172
}
173173

174174
@CEntryPoint(include = CEntryPoint.NotIncludedAutomatically.class, publishAs = CEntryPoint.Publish.NotPublished)
175-
private static int makeCodeMemoryExecutableWritable0(@SuppressWarnings("unused") IsolateThread targetIsolate, Pointer start, UnsignedWord size) {
176-
return RuntimeCodeInfoAccess.makeCodeMemoryExecutableWritable((CodePointer) start, size);
175+
private static void makeCodeMemoryExecutableWritable0(@SuppressWarnings("unused") IsolateThread targetIsolate, Pointer start, UnsignedWord size) {
176+
RuntimeCodeInfoAccess.makeCodeMemoryExecutableWritable((CodePointer) start, size);
177177
}
178178
}

0 commit comments

Comments
 (0)