Skip to content

Commit ed935b7

Browse files
committed
[GR-58575] SubstrateVM PLT/GOT Feature
PullRequest: graal/19015
2 parents 33025bc + ff719b3 commit ed935b7

File tree

44 files changed

+3136
-7
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

44 files changed

+3136
-7
lines changed

substratevm/mx.substratevm/suite.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -480,7 +480,7 @@
480480
"subDir": "src",
481481
"sourceDirs": ["src"],
482482
"dependencies": [
483-
"com.oracle.svm.core.graal.amd64",
483+
"com.oracle.svm.hosted",
484484
"com.oracle.svm.core.graal.aarch64",
485485
"com.oracle.svm.core.graal.riscv64",
486486
],
@@ -511,7 +511,7 @@
511511
"subDir": "src",
512512
"sourceDirs": ["src"],
513513
"dependencies": [
514-
"com.oracle.svm.core.graal.amd64",
514+
"com.oracle.svm.hosted",
515515
],
516516
"requiresConcealed" : {
517517
"jdk.internal.vm.ci" : [
@@ -639,8 +639,8 @@
639639
"sourceDirs": ["src"],
640640
"dependencies": [
641641
"com.oracle.objectfile",
642-
"com.oracle.svm.core",
643-
"com.oracle.graal.reachability"
642+
"com.oracle.graal.reachability",
643+
"com.oracle.svm.core.graal.amd64",
644644
],
645645
"requires" : [
646646
"jdk.jfr",

substratevm/src/com.oracle.svm.core.graal.aarch64/src/com/oracle/svm/core/graal/aarch64/SubstrateAArch64Backend.java

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,7 @@
7272
import com.oracle.svm.core.meta.SubstrateMethodPointerConstant;
7373
import com.oracle.svm.core.meta.SubstrateObjectConstant;
7474
import com.oracle.svm.core.nodes.SafepointCheckNode;
75+
import com.oracle.svm.core.pltgot.PLTGOTConfiguration;
7576
import com.oracle.svm.core.thread.VMThreads.StatusSupport;
7677
import com.oracle.svm.core.util.VMError;
7778

@@ -667,6 +668,14 @@ public Register getHeapBaseRegister() {
667668
protected int getVMPageSize() {
668669
return SubstrateOptions.getPageSize();
669670
}
671+
672+
@Override
673+
public void emitExitMethodAddressResolution(Value ip) {
674+
PLTGOTConfiguration configuration = PLTGOTConfiguration.singleton();
675+
RegisterValue exitThroughRegisterValue = configuration.getExitMethodAddressResolutionRegister(getRegisterConfig()).asValue(ip.getValueKind());
676+
emitMove(exitThroughRegisterValue, ip);
677+
append(configuration.createExitMethodAddressResolutionOp(exitThroughRegisterValue));
678+
}
670679
}
671680

672681
public class SubstrateAArch64NodeLIRBuilder extends AArch64NodeLIRBuilder implements SubstrateNodeLIRBuilder {

substratevm/src/com.oracle.svm.core.graal.amd64/src/com/oracle/svm/core/graal/amd64/SubstrateAMD64Backend.java

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,7 @@
9393
import com.oracle.svm.core.meta.SubstrateMethodPointerConstant;
9494
import com.oracle.svm.core.meta.SubstrateObjectConstant;
9595
import com.oracle.svm.core.nodes.SafepointCheckNode;
96+
import com.oracle.svm.core.pltgot.PLTGOTConfiguration;
9697
import com.oracle.svm.core.thread.VMThreads.StatusSupport;
9798
import com.oracle.svm.core.util.VMError;
9899

@@ -748,6 +749,14 @@ public void emitInstructionSynchronizationBarrier() {
748749
throw shouldNotReachHere("AMD64 does not need instruction synchronization");
749750
}
750751

752+
@Override
753+
public void emitExitMethodAddressResolution(Value ip) {
754+
PLTGOTConfiguration configuration = PLTGOTConfiguration.singleton();
755+
RegisterValue exitThroughRegisterValue = configuration.getExitMethodAddressResolutionRegister(getRegisterConfig()).asValue(ip.getValueKind());
756+
emitMove(exitThroughRegisterValue, ip);
757+
append(configuration.createExitMethodAddressResolutionOp(exitThroughRegisterValue));
758+
}
759+
751760
@Override
752761
public void emitFarReturn(AllocatableValue result, Value sp, Value ip, boolean fromMethodWithCalleeSavedRegisters) {
753762
append(new AMD64FarReturnOp(result, asAllocatable(sp), asAllocatable(ip), fromMethodWithCalleeSavedRegisters));
@@ -1813,7 +1822,7 @@ public void emitCode(CompilationResultBuilder crb, ResolvedJavaMethod installedC
18131822
}
18141823
}
18151824

1816-
private AMD64Assembler createAssemblerNoOptions() {
1825+
public AMD64Assembler createAssemblerNoOptions() {
18171826
OptionValues o = new OptionValues(EconomicMap.create());
18181827
return createAssembler(o);
18191828
}

substratevm/src/com.oracle.svm.core.graal.llvm/src/com/oracle/svm/core/graal/llvm/LLVMGenerator.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1147,6 +1147,11 @@ public void emitInstructionSynchronizationBarrier() {
11471147
throw unimplemented("the LLVM backend doesn't support instruction synchronization"); // ExcludeFromJacocoGeneratedReport
11481148
}
11491149

1150+
@Override
1151+
public void emitExitMethodAddressResolution(Value ip) {
1152+
throw unimplemented("the LLVM backend doesn't support PLT/GOT"); // ExcludeFromJacocoGeneratedReport
1153+
}
1154+
11501155
@Override
11511156
public <I extends LIRInstruction> I append(I op) {
11521157
throw unimplemented("the LLVM backend doesn't support LIR instructions"); // ExcludeFromJacocoGeneratedReport
Lines changed: 115 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,115 @@
1+
/*
2+
* Copyright (c) 2023, 2024, Oracle and/or its affiliates. All rights reserved.
3+
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4+
*
5+
* This code is free software; you can redistribute it and/or modify it
6+
* under the terms of the GNU General Public License version 2 only, as
7+
* published by the Free Software Foundation. Oracle designates this
8+
* particular file as subject to the "Classpath" exception as provided
9+
* by Oracle in the LICENSE file that accompanied this code.
10+
*
11+
* This code is distributed in the hope that it will be useful, but WITHOUT
12+
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13+
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14+
* version 2 for more details (a copy is included in the LICENSE file that
15+
* accompanied this code).
16+
*
17+
* You should have received a copy of the GNU General Public License version
18+
* 2 along with this work; if not, write to the Free Software Foundation,
19+
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20+
*
21+
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22+
* or visit www.oracle.com if you need additional information or have any
23+
* questions.
24+
*/
25+
package com.oracle.svm.core.posix.darwin;
26+
27+
import static com.oracle.svm.core.posix.headers.Mman.MAP_ANON;
28+
import static com.oracle.svm.core.posix.headers.Mman.MAP_FAILED;
29+
import static com.oracle.svm.core.posix.headers.Mman.MAP_PRIVATE;
30+
import static com.oracle.svm.core.posix.headers.Mman.PROT_READ;
31+
import static com.oracle.svm.core.posix.headers.Mman.PROT_WRITE;
32+
import static com.oracle.svm.core.posix.headers.Mman.NoTransitions.mmap;
33+
34+
import org.graalvm.nativeimage.StackValue;
35+
import org.graalvm.nativeimage.c.type.CIntPointer;
36+
import org.graalvm.nativeimage.c.type.WordPointer;
37+
import org.graalvm.word.Pointer;
38+
import org.graalvm.word.WordFactory;
39+
40+
import com.oracle.svm.core.Uninterruptible;
41+
import com.oracle.svm.core.c.CGlobalData;
42+
import com.oracle.svm.core.c.CGlobalDataFactory;
43+
import com.oracle.svm.core.c.function.CEntryPointErrors;
44+
import com.oracle.svm.core.headers.LibC;
45+
import com.oracle.svm.core.os.VirtualMemoryProvider;
46+
import com.oracle.svm.core.os.VirtualMemoryProvider.Access;
47+
import com.oracle.svm.core.pltgot.GOTHeapSupport;
48+
import com.oracle.svm.core.posix.headers.darwin.DarwinVirtualMemory;
49+
50+
public class DarwinGOTHeapSupport extends GOTHeapSupport {
51+
52+
private static final CGlobalData<WordPointer> DARWIN_GOT_START_ADDRESS = CGlobalDataFactory.createWord();
53+
54+
@Override
55+
@Uninterruptible(reason = "Called from uninterruptible code.", mayBeInlined = true)
56+
protected int initialize(WordPointer gotStartAddress) {
57+
int flags = MAP_ANON() | MAP_PRIVATE();
58+
Pointer gotMemory = mmap(WordFactory.nullPointer(), getPageAlignedGotSize(), PROT_READ() | PROT_WRITE(), flags, -1, 0);
59+
if (gotMemory.isNull() || gotMemory.equal(MAP_FAILED())) {
60+
return CEntryPointErrors.DYNAMIC_METHOD_ADDRESS_RESOLUTION_GOT_FD_CREATE_FAILED;
61+
}
62+
63+
Pointer gotStartInMemory = gotMemory.add(getGotOffsetFromStartOfMapping());
64+
LibC.memcpy(gotStartInMemory, IMAGE_GOT_BEGIN.get(), getGotSectionSize());
65+
66+
gotStartAddress.write(gotMemory);
67+
DARWIN_GOT_START_ADDRESS.get().write(gotMemory);
68+
69+
return CEntryPointErrors.NO_ERROR;
70+
}
71+
72+
@Override
73+
@Uninterruptible(reason = "Called from uninterruptible code.", mayBeInlined = true)
74+
public int mapGot(Pointer start) {
75+
WordPointer taskSelf = DarwinVirtualMemory.mach_task_self();
76+
77+
/* Unmap part of the heap address space that is designated for the GOT */
78+
int ret = DarwinVirtualMemory.vm_deallocate(DarwinVirtualMemory.mach_task_self(), start, getPageAlignedGotSize());
79+
if (ret != 0) {
80+
return CEntryPointErrors.DYNAMIC_METHOD_ADDRESS_RESOLUTION_GOT_MMAP_FAILED;
81+
}
82+
83+
WordPointer gotStart = StackValue.get(WordPointer.class);
84+
gotStart.write(start);
85+
86+
CIntPointer currentProt = StackValue.get(CIntPointer.class);
87+
CIntPointer maxProt = StackValue.get(CIntPointer.class);
88+
89+
int intFalse = 0;
90+
91+
/*
92+
* Map reserved address space for GOT to "global" GOT allocation, so that all isolates are
93+
* backed by the same table.
94+
*/
95+
ret = DarwinVirtualMemory.vm_remap(taskSelf, gotStart, getPageAlignedGotSize(), WordFactory.nullPointer(), intFalse,
96+
taskSelf, DARWIN_GOT_START_ADDRESS.get().read(), intFalse, currentProt, maxProt, DarwinVirtualMemory.VM_INHERIT_SHARE());
97+
if (ret != 0) {
98+
return CEntryPointErrors.DYNAMIC_METHOD_ADDRESS_RESOLUTION_GOT_WRONG_MMAP;
99+
}
100+
101+
/*
102+
* The new mapping "inherits" cur_prot and max_prot from the original mapping, but another
103+
* isolate could race trying to write the original GOT => the new mapping could inherit
104+
* cur_prot=RW. Ensure that the new-mapping remains read-only, regardless of races.
105+
*/
106+
if (currentProt.read() != PROT_READ()) {
107+
ret = VirtualMemoryProvider.get().protect(start, getPageAlignedGotSize(), Access.READ);
108+
if (ret != 0) {
109+
return ret;
110+
}
111+
}
112+
113+
return CEntryPointErrors.NO_ERROR;
114+
}
115+
}
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
/*
2+
* Copyright (c) 2023, 2024, Oracle and/or its affiliates. All rights reserved.
3+
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4+
*
5+
* This code is free software; you can redistribute it and/or modify it
6+
* under the terms of the GNU General Public License version 2 only, as
7+
* published by the Free Software Foundation. Oracle designates this
8+
* particular file as subject to the "Classpath" exception as provided
9+
* by Oracle in the LICENSE file that accompanied this code.
10+
*
11+
* This code is distributed in the hope that it will be useful, but WITHOUT
12+
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13+
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14+
* version 2 for more details (a copy is included in the LICENSE file that
15+
* accompanied this code).
16+
*
17+
* You should have received a copy of the GNU General Public License version
18+
* 2 along with this work; if not, write to the Free Software Foundation,
19+
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20+
*
21+
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22+
* or visit www.oracle.com if you need additional information or have any
23+
* questions.
24+
*/
25+
package com.oracle.svm.core.posix.darwin;
26+
27+
import org.graalvm.nativeimage.ImageSingletons;
28+
import org.graalvm.nativeimage.Platform;
29+
30+
import com.oracle.svm.core.code.DynamicMethodAddressResolutionHeapSupport;
31+
import com.oracle.svm.core.feature.AutomaticallyRegisteredFeature;
32+
import com.oracle.svm.core.feature.InternalFeature;
33+
import com.oracle.svm.hosted.pltgot.PLTGOTOptions;
34+
35+
@AutomaticallyRegisteredFeature
36+
public class DarwinPLTGOTFeature implements InternalFeature {
37+
38+
@Override
39+
public boolean isInConfiguration(IsInConfigurationAccess access) {
40+
return Platform.includedIn(Platform.DARWIN.class) && PLTGOTOptions.EnablePLTGOT.getValue();
41+
}
42+
43+
@Override
44+
public void afterRegistration(AfterRegistrationAccess access) {
45+
ImageSingletons.add(DynamicMethodAddressResolutionHeapSupport.class, new DarwinGOTHeapSupport());
46+
}
47+
}

0 commit comments

Comments
 (0)