Skip to content

Commit f4895de

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 f4895de

5 files changed

Lines changed: 159 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: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
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+
import org.graalvm.nativeimage.Platform;
29+
import org.graalvm.nativeimage.Platforms;
30+
31+
import com.oracle.svm.shared.c.libc.LibCKind;
32+
import com.oracle.svm.shared.meta.GuestFold;
33+
import com.oracle.svm.shared.singletons.traits.BuiltinTraits.BuildtimeAccessOnly;
34+
import com.oracle.svm.shared.singletons.traits.BuiltinTraits.NoLayeredCallbacks;
35+
import com.oracle.svm.shared.singletons.traits.SingletonTraits;
36+
37+
/**
38+
* Guest-owned target Linux libc identity derived from the authoritative builder selection.
39+
* <p>
40+
* Although the query methods are called from runtime-owned code, every query is
41+
* {@link GuestFold folded} while the image is built. The fold executes in the guest context and
42+
* replaces the call with a boolean constant, so neither this singleton nor its
43+
* {@link ImageSingletons#lookup(Class) lookup} is needed at image runtime. Consequently, this
44+
* singleton deliberately permits build-time access only.
45+
*/
46+
@Platforms(Platform.LINUX.class)
47+
@SingletonTraits(access = BuildtimeAccessOnly.class, layeredCallbacks = NoLayeredCallbacks.class)
48+
public final class SubstrateGuestLibC {
49+
50+
private final LibCKind kind;
51+
52+
/**
53+
* Creates the guest-owned libc metadata from a shared enum name. Passing the name lets the enum
54+
* value be materialized inside the guest context instead of transferring a builder object.
55+
*
56+
* @param kindName the {@link LibCKind} constant name
57+
*/
58+
public SubstrateGuestLibC(String kindName) {
59+
this.kind = LibCKind.valueOf(kindName);
60+
}
61+
62+
/** Returns whether the target uses musl libc. */
63+
@GuestFold
64+
public static boolean isMusl() {
65+
return singleton().kind == LibCKind.MUSL;
66+
}
67+
68+
/** Returns whether the target uses glibc. */
69+
@GuestFold
70+
public static boolean isGLibC() {
71+
return singleton().kind == LibCKind.GLIBC;
72+
}
73+
74+
/** Returns whether the target uses Bionic libc. */
75+
@GuestFold
76+
public static boolean isBionic() {
77+
return singleton().kind == LibCKind.BIONIC;
78+
}
79+
80+
/** Returns the libc metadata installed in the guest singleton registry. */
81+
private static SubstrateGuestLibC singleton() {
82+
return ImageSingletons.lookup(SubstrateGuestLibC.class);
83+
}
84+
}

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

Lines changed: 29 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,9 @@ protected void setupNativeImage(OptionValues options, Map<ResolvedJavaMethod, CE
11041109
featureHandler.forEachFeature(feature -> feature.afterRegistration(access));
11051110
DynamicAccessSupport.setRegistrationSealed();
11061111
setDefaultLibCIfMissing();
1112+
if (Platform.includedIn(Platform.LINUX.class)) {
1113+
setupGuestLibC();
1114+
}
11071115
MainEntryPoint accessMainEntryPoint = access.getMainEntryPoint();
11081116
if (accessMainEntryPoint != null) {
11091117
setAndVerifyMainEntryPoint(accessMainEntryPoint, entryPoints);
@@ -1374,6 +1382,27 @@ private static void setupGuestTargetDescription(SubstrateTarget target) {
13741382
GuestImageSingletonSupport.add(SubstrateGuestTarget.class, guestTargetDescription);
13751383
}
13761384

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

0 commit comments

Comments
 (0)