Skip to content

Commit 24c965b

Browse files
committed
[GR-44503] Add support for a symbol encoder
PullRequest: graal/19783
2 parents 318a834 + 56fe5b4 commit 24c965b

File tree

21 files changed

+482
-62
lines changed

21 files changed

+482
-62
lines changed

docs/reference-manual/native-image/BuildOutput.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -279,6 +279,13 @@ To fix this, ensure that proper GAV coordinates (Group ID, Artifact ID, and Vers
279279

280280
For more information, see [Software Bill of Materials](../../security/native-image.md).
281281

282+
#### <a name="glossary-obfuscation"></a>Obfuscation
283+
This section indicates whether obfuscation was applied and provides related statistics.
284+
Obfuscation is applied to your application code and third-party dependencies, but not to the JDK or [Substrate VM](https://github.com/oracle/graal/tree/master/substratevm) code.
285+
The following elements are obfuscated: module, package, and class names; method and source file names in stack traces; and field names in heap dumps.
286+
The following elements are not obfuscated: symbols affected by registrations in reachability metadata; modules and packages that contain a class which loads a resource; annotations; lambdas; and proxies.
287+
Use `-H:EnableObfuscation=export-mapping` to export a build artifact containing the mappings from original to obfuscated names.
288+
282289
#### <a name="glossary-backwards-edge-cfi"></a>Backwards-Edge Control-Flow Integrity (CFI)
283290
Control-Flow Integrity (CFI) can be enforced with the experimental `-H:CFI=HW` option.
284291
This feature is currently only available for code compiled by Graal for Linux AArch64 and leverages pointer authentication codes (PAC) to ensure integrity of a function's return address.
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
/*
2+
* Copyright (c) 2025, 2025, 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;
26+
27+
/**
28+
* Contains constants shared between the driver and the image builder.
29+
*/
30+
public final class SharedConstants {
31+
32+
/**
33+
* The name of the environment variable containing the path to the temporary directory that is
34+
* available during the process lifetime of the Native Image driver.
35+
*/
36+
public static final String DRIVER_TEMP_DIR_ENV_VARIABLE = "DRIVER_TEMP_DIR_ENV_VARIABLE";
37+
38+
/**
39+
* The name of the Java environment variable used to indicate that it is a build initiated due
40+
* to a {@link com.oracle.svm.core.util.ExitStatus#REBUILD_AFTER_ANALYSIS exit status}. The
41+
* environment variable is not set for all other builds.
42+
*/
43+
public static final String REBUILD_AFTER_ANALYSIS_MARKER = "com.oracle.svm.rebuild";
44+
}

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

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@
3535
import java.util.Objects;
3636
import java.util.Set;
3737

38+
import com.oracle.svm.core.encoder.SymbolEncoder;
3839
import org.graalvm.collections.EconomicMap;
3940
import org.graalvm.collections.Equivalence;
4041
import org.graalvm.nativeimage.ImageSingletons;
@@ -127,6 +128,7 @@ protected void recordFrame(ResolvedJavaMethod method, Infopoint infopoint, boole
127128

128129
public abstract static class SourceFieldsFromMethod extends Customization {
129130
private final HostedStringDeduplication stringTable = HostedStringDeduplication.singleton();
131+
private final SymbolEncoder encoder = SymbolEncoder.singleton();
130132

131133
@Override
132134
protected void fillSourceFields(ResolvedJavaMethod method, FrameInfoQueryResult resultFrameInfo) {
@@ -144,7 +146,7 @@ protected void fillSourceFields(ResolvedJavaMethod method, FrameInfoQueryResult
144146
*/
145147
int sourceMethodModifiers = method.getModifiers();
146148
String methodSignature = method.getSignature().toMethodDescriptor();
147-
String sourceMethodName = stringTable.deduplicate(source.getMethodName(), true);
149+
String sourceMethodName = stringTable.deduplicate(encoder.encodeMethod(source.getMethodName(), sourceClass), true);
148150
String sourceMethodSignature = CodeInfoEncoder.shouldEncodeAllMethodMetadata() ? stringTable.deduplicate(methodSignature, true) : methodSignature;
149151
resultFrameInfo.setSourceFields(sourceClass, sourceMethodName, sourceMethodSignature, sourceMethodModifiers);
150152
}
Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
/*
2+
* Copyright (c) 2025, 2025, 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.encoder;
26+
27+
/**
28+
* This encoder returns the symbol names unmodified.
29+
*/
30+
public final class IdentitySymbolEncoder implements SymbolEncoder {
31+
@Override
32+
public String encodeModule(String moduleName) {
33+
return moduleName;
34+
}
35+
36+
@Override
37+
public String encodeClass(String className) {
38+
return className;
39+
}
40+
41+
@Override
42+
public String encodePackage(String packageName) {
43+
return packageName;
44+
}
45+
46+
@Override
47+
public String encodeSourceFile(String sourceFileName, Class<?> clazz) {
48+
return sourceFileName;
49+
}
50+
51+
@Override
52+
public String encodeMethod(String methodName, Class<?> clazz) {
53+
return methodName;
54+
}
55+
56+
@Override
57+
public String encodeField(String fieldName, Class<?> clazz) {
58+
return fieldName;
59+
}
60+
}
Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
/*
2+
* Copyright (c) 2025, 2025, 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.encoder;
26+
27+
import org.graalvm.nativeimage.ImageSingletons;
28+
import org.graalvm.nativeimage.Platform;
29+
import org.graalvm.nativeimage.Platforms;
30+
31+
import jdk.graal.compiler.api.replacements.Fold;
32+
33+
/**
34+
* This interface provides hooks to encode the names of modules, packages, classes, source files,
35+
* methods, and fields. Encoding these symbols allows an implementation to control which names are
36+
* present in the image, as well as those included in stack traces and heap dumps.
37+
*/
38+
@Platforms(Platform.HOSTED_ONLY.class)
39+
public interface SymbolEncoder {
40+
String encodeModule(String moduleName);
41+
42+
String encodePackage(String packageName);
43+
44+
String encodeClass(String className);
45+
46+
String encodeSourceFile(String sourceFileName, Class<?> clazz);
47+
48+
String encodeMethod(String methodName, Class<?> clazz);
49+
50+
String encodeField(String fieldName, Class<?> clazz);
51+
52+
@Fold
53+
static SymbolEncoder singleton() {
54+
return ImageSingletons.lookup(SymbolEncoder.class);
55+
}
56+
}
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
/*
2+
* Copyright (c) 2025, 2025, 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.encoder;
26+
27+
import org.graalvm.nativeimage.ImageSingletons;
28+
29+
import com.oracle.svm.core.feature.AutomaticallyRegisteredFeature;
30+
import com.oracle.svm.core.feature.InternalFeature;
31+
32+
/**
33+
* Ensures that the {@link IdentitySymbolEncoder} is used.
34+
*/
35+
@AutomaticallyRegisteredFeature
36+
public class SymbolEncoderFeature implements InternalFeature {
37+
@Override
38+
public void afterRegistration(AfterRegistrationAccess access) {
39+
registerIdentityStringEncoder();
40+
}
41+
42+
protected void registerIdentityStringEncoder() {
43+
ImageSingletons.add(SymbolEncoder.class, new IdentitySymbolEncoder());
44+
}
45+
}

substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/hub/ClassForNameSupport.java

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,9 @@
2929

3030
import java.lang.reflect.Modifier;
3131
import java.util.EnumSet;
32+
import java.util.HashSet;
3233
import java.util.Objects;
34+
import java.util.Set;
3335
import java.util.function.BooleanSupplier;
3436

3537
import org.graalvm.collections.EconomicMap;
@@ -280,6 +282,16 @@ public static Class<?> forNameOrNull(String className, ClassLoader classLoader)
280282
}
281283
}
282284

285+
@Platforms(Platform.HOSTED_ONLY.class)
286+
public Set<String> getKnownClassNames() {
287+
EconomicMap<String, ?> map = respectClassLoader() ? knownClassNames : knownClasses;
288+
Set<String> set = new HashSet<>(map.size());
289+
for (String key : map.getKeys()) {
290+
set.add(key);
291+
}
292+
return set;
293+
}
294+
283295
public static Class<?> forName(String className, ClassLoader classLoader) throws ClassNotFoundException {
284296
return forName(className, classLoader, false);
285297
}

substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/jdk/Resources.java

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@
4343
import java.util.stream.Collectors;
4444
import java.util.stream.StreamSupport;
4545

46+
import com.oracle.svm.core.encoder.SymbolEncoder;
4647
import org.graalvm.collections.EconomicMap;
4748
import org.graalvm.collections.MapCursor;
4849
import org.graalvm.nativeimage.ImageInfo;
@@ -89,6 +90,7 @@ public final class Resources implements MultiLayeredImageSingleton, UnsavedSingl
8990

9091
private static final int INVALID_TIMESTAMP = -1;
9192
public static final char RESOURCES_INTERNAL_PATH_SEPARATOR = '/';
93+
private final SymbolEncoder encoder = SymbolEncoder.singleton();
9294

9395
/**
9496
* @return the singleton corresponding to this layer's resources in a layered build, the unique
@@ -180,6 +182,11 @@ public Iterable<ConditionalRuntimeValue<ResourceStorageEntryBase>> resources() {
180182
return resources.getValues();
181183
}
182184

185+
@Platforms(Platform.HOSTED_ONLY.class)
186+
public Iterable<ModuleResourceKey> resourceKeys() {
187+
return resources.getKeys();
188+
}
189+
183190
@Platforms(Platform.HOSTED_ONLY.class)
184191
public int count() {
185192
return resources.size();
@@ -318,7 +325,7 @@ public void registerIncludePattern(ConfigurationCondition condition, String modu
318325
assert MissingRegistrationUtils.throwMissingRegistrationErrors();
319326
synchronized (requestedPatterns) {
320327
updateTimeStamp();
321-
requestedPatterns.put(new RequestedPattern(module, handleEscapedCharacters(pattern)), RuntimeConditionSet.createHosted(condition));
328+
requestedPatterns.put(new RequestedPattern(encoder.encodeModule(module), handleEscapedCharacters(pattern)), RuntimeConditionSet.createHosted(condition));
322329
}
323330
}
324331

substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/jdk/ServiceCatalogSupport.java

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@
3030
import java.util.concurrent.ConcurrentHashMap;
3131
import java.util.stream.Collectors;
3232

33+
import com.oracle.svm.core.encoder.SymbolEncoder;
3334
import org.graalvm.nativeimage.ImageSingletons;
3435
import org.graalvm.nativeimage.Platform;
3536
import org.graalvm.nativeimage.Platforms;
@@ -88,9 +89,10 @@ public void enableServiceCatalogMapTransformer(Feature.BeforeAnalysisAccess acce
8889
var omittedProviders = omittedServiceProviders.get(service);
8990
providers = providers.stream()
9091
.filter(p -> !omittedProviders.contains(p))
91-
.collect(Collectors.toList());
92+
.toList();
9293
}
93-
return providers;
94+
SymbolEncoder encoder = SymbolEncoder.singleton();
95+
return providers.stream().map(encoder::encodeClass).toList();
9496
});
9597
}
9698
}

substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/util/ExitStatus.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ public enum ExitStatus {
3939
DRIVER_ERROR(20),
4040
DRIVER_TO_BUILDER_ERROR(21),
4141
WATCHDOG_EXIT(30),
42+
REBUILD_AFTER_ANALYSIS(40),
4243
MISSING_METADATA(172),
4344
UNKNOWN(255);
4445

0 commit comments

Comments
 (0)