diff --git a/src/hotspot/share/cds/filemap.cpp b/src/hotspot/share/cds/filemap.cpp index 186dca4fa13..067301aacdf 100644 --- a/src/hotspot/share/cds/filemap.cpp +++ b/src/hotspot/share/cds/filemap.cpp @@ -1362,6 +1362,13 @@ bool FileMapInfo::map_aot_code_region(ReservedSpace rs) { return false; } else { assert(mapped_base == requested_base, "must be"); + + if (VerifySharedSpaces && !r->check_region_crc(mapped_base)) { + aot_log_error(aot)("region %d CRC error", AOTMetaspace::ac); + os::unmap_memory(mapped_base, r->used_aligned()); + return false; + } + r->set_mapped_from_file(true); r->set_mapped_base(mapped_base); aot_log_info(aot)("Mapped static region #%d at base " INTPTR_FORMAT " top " INTPTR_FORMAT " (%s)", diff --git a/test/hotspot/jtreg/runtime/cds/appcds/aotCache/AOTCacheConsistency.java b/test/hotspot/jtreg/runtime/cds/appcds/aotCache/AOTCacheConsistency.java new file mode 100644 index 00000000000..90e1c765e61 --- /dev/null +++ b/test/hotspot/jtreg/runtime/cds/appcds/aotCache/AOTCacheConsistency.java @@ -0,0 +1,76 @@ +/* + * Copyright (c) 2026, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + * + */ + +/* + * @test + * @key randomness + * @summary AOTCacheConsistency This test checks that there is a CRC validation of the AOT Cache regions. + * @bug 8382166 + * @requires vm.cds.supports.aot.class.linking + * @library /test/lib + * @build jdk.test.whitebox.WhiteBox AOTCacheConsistency HelloWorld + * @run driver jdk.test.lib.helpers.ClassFileInstaller jdk.test.whitebox.WhiteBox + * @run driver jdk.test.lib.helpers.ClassFileInstaller -jar app.jar HelloWorld + * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI AOTCacheConsistency + */ + +import jdk.test.lib.cds.CDSArchiveUtils; +import jdk.test.lib.cds.SimpleCDSAppTester; +import jdk.test.lib.process.OutputAnalyzer; +import java.io.File; + +public class AOTCacheConsistency { + public static void main(String args[]) throws Exception { + // Train and run the app + SimpleCDSAppTester tester = SimpleCDSAppTester.of("AOTCacheConsistency") + .classpath("app.jar") + .appCommandLine("HelloWorld") + .setProductionChecker((OutputAnalyzer out) -> { + out.shouldContain("HelloWorld"); + }) + .runAOTWorkflow(); + + String aotCache = tester.aotCacheFile(); + + String[] regions = CDSArchiveUtils.getRegions(); + String orig = aotCache + ".orig"; + CDSArchiveUtils.copyArchiveFile(new File(aotCache), orig); // save original copy + + // Modify each of the region individually. The production should fail to run + // with these args; + String extraVMArgs[] = {"-XX:+VerifySharedSpaces", "-XX:AOTMode=on"}; + tester.setCheckExitValue(false); + + for (int i = 0; i < regions.length; i++) { + File f = CDSArchiveUtils.copyArchiveFile(new File(orig), aotCache); + System.out.println("\n=======\nTesting region " + i + " = " + regions[i]); + if (CDSArchiveUtils.modifyRegionContent(i, f)) { + tester.setProductionChecker((OutputAnalyzer out) -> { + out.shouldContain("Checksum verification failed."); + }); + tester.rerunProduction(extraVMArgs); + } + } + } +} \ No newline at end of file diff --git a/test/lib/jdk/test/lib/cds/CDSAppTester.java b/test/lib/jdk/test/lib/cds/CDSAppTester.java index 3eac8a35a37..80ff54021f5 100644 --- a/test/lib/jdk/test/lib/cds/CDSAppTester.java +++ b/test/lib/jdk/test/lib/cds/CDSAppTester.java @@ -60,6 +60,10 @@ abstract public class CDSAppTester { private boolean generateBaseArchive = false; private String[] baseArchiveOptions = new String[0]; + public String aotCacheFile() { + return this.aotCacheFile; + } + /** * All files created in the CDS/AOT workflow will be name + extension. E.g. * - name.aot diff --git a/test/lib/jdk/test/lib/cds/CDSArchiveUtils.java b/test/lib/jdk/test/lib/cds/CDSArchiveUtils.java index 35cee750822..04922654592 100644 --- a/test/lib/jdk/test/lib/cds/CDSArchiveUtils.java +++ b/test/lib/jdk/test/lib/cds/CDSArchiveUtils.java @@ -75,9 +75,14 @@ public class CDSArchiveUtils { "ro", // ReadOnly "bm", // relocation bitmaps "hp", // heap + "ac", // aot code }; private static int num_regions = shared_region_name.length; + public static String[] getRegions() { + return shared_region_name; + } + static { WhiteBox wb; try { diff --git a/test/lib/jdk/test/lib/cds/SimpleCDSAppTester.java b/test/lib/jdk/test/lib/cds/SimpleCDSAppTester.java index a8bba9c76e2..73e45711fe9 100644 --- a/test/lib/jdk/test/lib/cds/SimpleCDSAppTester.java +++ b/test/lib/jdk/test/lib/cds/SimpleCDSAppTester.java @@ -211,4 +211,22 @@ public class SimpleCDSAppTester { tester.run(args); return this; } + + public SimpleCDSAppTester rerunProduction(String... extraVmArgs) throws Exception { + tester.productionRun(extraVmArgs); + return this; + } + + public SimpleCDSAppTester rerunProduction(String[] extraVmArgs, String... extraAppArgs) throws Exception { + tester.productionRun(extraVmArgs, extraAppArgs); + return this; + } + + public String aotCacheFile() { + return tester.aotCacheFile(); + } + + public void setCheckExitValue(boolean b) { + tester.setCheckExitValue(b); + } }