Skip to content

Commit 7c8ea83

Browse files
committed
Separate builder and guest libc selection state
Keep the existing LibCBase API unchanged for builder and host-analyzed callers. Introduce a shared LibCKind value, rematerialize it in the guest context, and expose guest-owned folded predicates where runtime code is already guest-owned. Migrate PosixPlatformThreads to that guest state. Truffle NFI remains on its existing builder-folded LibCBase query until that code is migrated separately.
1 parent 1be230a commit 7c8ea83

5 files changed

Lines changed: 149 additions & 6 deletions

File tree

substratevm/mx.substratevm/suite.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -588,6 +588,8 @@
588588
"com.oracle.svm.hosted",
589589
"com.oracle.svm.core.graal.aarch64",
590590
"com.oracle.svm.core.graal.riscv64",
591+
# GR-73521: Remove once PosixPlatformThreads moves to guest-owned code.
592+
"SVM_GUEST_STAGING",
591593
],
592594
"requiresConcealed" : {
593595
"java.base" : [

substratevm/src/com.oracle.svm.core.posix/src/com/oracle/svm/core/posix/thread/PosixPlatformThreads.java

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -48,16 +48,13 @@
4848
import com.oracle.svm.core.annotate.Inject;
4949
import com.oracle.svm.core.annotate.RecomputeFieldValue;
5050
import com.oracle.svm.core.annotate.TargetClass;
51-
import com.oracle.svm.core.c.libc.BionicLibC;
52-
import com.oracle.svm.core.c.libc.GLibC;
53-
import com.oracle.svm.core.c.libc.LibCBase;
54-
import com.oracle.svm.core.c.libc.MuslLibC;
5551
import com.oracle.svm.core.graal.stackvalue.UnsafeStackValue;
5652
import com.oracle.svm.core.memory.NativeMemory;
5753
import com.oracle.svm.core.nmt.NmtCategory;
5854
import com.oracle.svm.core.posix.PosixUtils;
5955
import com.oracle.svm.core.posix.headers.Errno;
6056
import com.oracle.svm.core.posix.headers.Pthread;
57+
import com.oracle.svm.guest.staging.config.SubstrateGuestLibC;
6158
import com.oracle.svm.core.posix.headers.Pthread.pthread_attr_t;
6259
import com.oracle.svm.core.posix.headers.Pthread.pthread_cond_t;
6360
import com.oracle.svm.core.posix.headers.Pthread.pthread_mutex_t;
@@ -150,10 +147,10 @@ private static UnsignedWord computeNativeStackSize(pthread_attr_t attributes, lo
150147
@Uninterruptible(reason = CALLED_FROM_UNINTERRUPTIBLE_CODE, mayBeInlined = true)
151148
public static UnsignedWord computeGuardSizeIncludedInStackSize(pthread_attr_t attr) {
152149
if (Platform.includedIn(Platform.LINUX.class)) {
153-
if (LibCBase.targetLibCIs(MuslLibC.class)) {
150+
if (SubstrateGuestLibC.isMusl()) {
154151
/* pthread_attr_getstack() already excludes the guard size correctly. */
155152
return Word.zero();
156-
} else if (LibCBase.targetLibCIs(GLibC.class) || LibCBase.targetLibCIs(BionicLibC.class)) {
153+
} else if (SubstrateGuestLibC.isGLibC() || SubstrateGuestLibC.isBionic()) {
157154
/* pthread_attr_getstack() includes the guard size, so determine and subtract the guard size. */
158155
WordPointer guardSizePtr = StackValue.get(WordPointer.class);
159156
if (Pthread.pthread_attr_getguardsize(attr, guardSizePtr) != 0) {
Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
/*
2+
* Copyright (c) 2026, 2026, 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.guest.staging.config;
26+
27+
import org.graalvm.nativeimage.ImageSingletons;
28+
29+
import com.oracle.svm.shared.c.libc.LibCKind;
30+
import com.oracle.svm.shared.meta.GuestFold;
31+
import com.oracle.svm.shared.singletons.traits.BuiltinTraits.BuildtimeAccessOnly;
32+
import com.oracle.svm.shared.singletons.traits.BuiltinTraits.NoLayeredCallbacks;
33+
import com.oracle.svm.shared.singletons.traits.SingletonTraits;
34+
35+
/**
36+
* Guest-owned target libc identity derived from the authoritative builder selection.
37+
* <p>
38+
* Although the query methods are called from runtime-owned code, every query is
39+
* {@link GuestFold folded} while the image is built. The fold executes in the guest context and
40+
* replaces the call with a boolean constant, so neither this singleton nor its
41+
* {@link ImageSingletons#lookup(Class) lookup} is needed at image runtime. Consequently, this
42+
* singleton deliberately permits build-time access only.
43+
*/
44+
@SingletonTraits(access = BuildtimeAccessOnly.class, layeredCallbacks = NoLayeredCallbacks.class)
45+
public final class SubstrateGuestLibC {
46+
47+
private final LibCKind kind;
48+
49+
/**
50+
* Creates the guest-owned libc metadata from a shared enum name. Passing the name lets the enum
51+
* value be materialized inside the guest context instead of transferring a builder object.
52+
*
53+
* @param kindName the {@link LibCKind} constant name
54+
*/
55+
public SubstrateGuestLibC(String kindName) {
56+
this.kind = LibCKind.valueOf(kindName);
57+
}
58+
59+
/** Returns whether the target uses musl libc. */
60+
@GuestFold
61+
public static boolean isMusl() {
62+
return singleton().kind == LibCKind.MUSL;
63+
}
64+
65+
/** Returns whether the target uses glibc. */
66+
@GuestFold
67+
public static boolean isGLibC() {
68+
return singleton().kind == LibCKind.GLIBC;
69+
}
70+
71+
/** Returns whether the target uses Bionic libc. */
72+
@GuestFold
73+
public static boolean isBionic() {
74+
return singleton().kind == LibCKind.BIONIC;
75+
}
76+
77+
/** Returns the libc metadata installed in the guest singleton registry. */
78+
private static SubstrateGuestLibC singleton() {
79+
return ImageSingletons.lookup(SubstrateGuestLibC.class);
80+
}
81+
}

substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/NativeImageGenerator.java

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -130,7 +130,10 @@
130130
import com.oracle.svm.core.ParsingReason;
131131
import com.oracle.svm.core.SubstrateOptions;
132132
import com.oracle.svm.core.SubstrateTarget;
133+
import com.oracle.svm.core.c.libc.BionicLibC;
134+
import com.oracle.svm.core.c.libc.GLibC;
133135
import com.oracle.svm.core.c.libc.LibCBase;
136+
import com.oracle.svm.core.c.libc.MuslLibC;
134137
import com.oracle.svm.core.c.libc.NoLibC;
135138
import com.oracle.svm.core.c.libc.TemporaryBuildDirectoryProvider;
136139
import com.oracle.svm.core.c.struct.OffsetOf;
@@ -174,6 +177,7 @@
174177
import com.oracle.svm.core.util.UserError;
175178
import com.oracle.svm.guest.staging.ArgsSupport;
176179
import com.oracle.svm.guest.staging.JavaMainSupport;
180+
import com.oracle.svm.guest.staging.config.SubstrateGuestLibC;
177181
import com.oracle.svm.guest.staging.config.SubstrateGuestTarget;
178182
import com.oracle.svm.guest.staging.jdk.RuntimeSupport;
179183
import com.oracle.svm.guest.staging.option.RuntimeOptionValidationSupport;
@@ -273,6 +277,7 @@
273277
import com.oracle.svm.hosted.util.CPUTypeAMD64;
274278
import com.oracle.svm.hosted.util.CPUTypeRISCV64;
275279
import com.oracle.svm.shared.ImageLayerBuildingSupportProvider;
280+
import com.oracle.svm.shared.c.libc.LibCKind;
276281
import com.oracle.svm.shared.option.HostedOptionValues;
277282
import com.oracle.svm.shared.option.OptionClassFilter;
278283
import com.oracle.svm.shared.option.SubstrateOptionsParser;
@@ -1104,6 +1109,7 @@ protected void setupNativeImage(OptionValues options, Map<ResolvedJavaMethod, CE
11041109
featureHandler.forEachFeature(feature -> feature.afterRegistration(access));
11051110
DynamicAccessSupport.setRegistrationSealed();
11061111
setDefaultLibCIfMissing();
1112+
setupGuestLibC();
11071113
MainEntryPoint accessMainEntryPoint = access.getMainEntryPoint();
11081114
if (accessMainEntryPoint != null) {
11091115
setAndVerifyMainEntryPoint(accessMainEntryPoint, entryPoints);
@@ -1374,6 +1380,26 @@ private static void setupGuestTargetDescription(SubstrateTarget target) {
13741380
GuestImageSingletonSupport.add(SubstrateGuestTarget.class, guestTargetDescription);
13751381
}
13761382

1383+
/**
1384+
* Installs the guest-owned target libc identity derived from the authoritative builder
1385+
* selection. Only the enum name crosses the context boundary; the enum value and singleton are
1386+
* created in the guest context. The singleton is used only while folding guest queries during
1387+
* image building; the folded boolean constants are what remain in runtime code.
1388+
*/
1389+
private static void setupGuestLibC() {
1390+
GuestAccess access = GuestAccess.get();
1391+
LibCKind kind = switch (LibCBase.singleton()) {
1392+
case GLibC _ -> LibCKind.GLIBC;
1393+
case MuslLibC _ -> LibCKind.MUSL;
1394+
case BionicLibC _ -> LibCKind.BIONIC;
1395+
case NoLibC _ -> LibCKind.NOT_APPLICABLE;
1396+
case LibCBase libC -> throw VMError.shouldNotReachHere("Unknown target libc implementation: " + libC.getClass().getName());
1397+
};
1398+
ResolvedJavaMethod ctor = JVMCIReflectionUtil.getDeclaredConstructor(access.getProviders().getMetaAccess(), SubstrateGuestLibC.class, String.class);
1399+
JavaConstant guestLibC = access.invoke(ctor, null, access.asGuestString(kind.name()));
1400+
GuestImageSingletonSupport.add(SubstrateGuestLibC.class, guestLibC);
1401+
}
1402+
13771403
/**
13781404
* Filters out internal user features from the report.
13791405
*/
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
/*
2+
* Copyright (c) 2026, 2026, 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.shared.c.libc;
26+
27+
/** Identifies the target C library without carrying any builder-specific behavior. */
28+
public enum LibCKind {
29+
/** GNU C Library. */
30+
GLIBC,
31+
/** musl libc. */
32+
MUSL,
33+
/** Android Bionic libc. */
34+
BIONIC,
35+
/** No target C library applies. */
36+
NOT_APPLICABLE
37+
}

0 commit comments

Comments
 (0)