xref: /aosp_15_r20/art/dex2oat/dex2oat_vdex_test.cc (revision 795d594fd825385562da6b089ea9b2033f3abf5a)
1*795d594fSAndroid Build Coastguard Worker /*
2*795d594fSAndroid Build Coastguard Worker  * Copyright (C) 2020 The Android Open Source Project
3*795d594fSAndroid Build Coastguard Worker  *
4*795d594fSAndroid Build Coastguard Worker  * Licensed under the Apache License, Version 2.0 (the "License");
5*795d594fSAndroid Build Coastguard Worker  * you may not use this file except in compliance with the License.
6*795d594fSAndroid Build Coastguard Worker  * You may obtain a copy of the License at
7*795d594fSAndroid Build Coastguard Worker  *
8*795d594fSAndroid Build Coastguard Worker  *      http://www.apache.org/licenses/LICENSE-2.0
9*795d594fSAndroid Build Coastguard Worker  *
10*795d594fSAndroid Build Coastguard Worker  * Unless required by applicable law or agreed to in writing, software
11*795d594fSAndroid Build Coastguard Worker  * distributed under the License is distributed on an "AS IS" BASIS,
12*795d594fSAndroid Build Coastguard Worker  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13*795d594fSAndroid Build Coastguard Worker  * See the License for the specific language governing permissions and
14*795d594fSAndroid Build Coastguard Worker  * limitations under the License.
15*795d594fSAndroid Build Coastguard Worker  */
16*795d594fSAndroid Build Coastguard Worker 
17*795d594fSAndroid Build Coastguard Worker #include <string>
18*795d594fSAndroid Build Coastguard Worker #include <vector>
19*795d594fSAndroid Build Coastguard Worker 
20*795d594fSAndroid Build Coastguard Worker #include "android-base/result-gmock.h"
21*795d594fSAndroid Build Coastguard Worker #include "android-base/result.h"
22*795d594fSAndroid Build Coastguard Worker #include "common_runtime_test.h"
23*795d594fSAndroid Build Coastguard Worker #include "dex2oat_environment_test.h"
24*795d594fSAndroid Build Coastguard Worker #include "vdex_file.h"
25*795d594fSAndroid Build Coastguard Worker #include "verifier/verifier_deps.h"
26*795d594fSAndroid Build Coastguard Worker 
27*795d594fSAndroid Build Coastguard Worker namespace art {
28*795d594fSAndroid Build Coastguard Worker 
29*795d594fSAndroid Build Coastguard Worker using ::android::base::Result;
30*795d594fSAndroid Build Coastguard Worker using ::android::base::testing::HasValue;
31*795d594fSAndroid Build Coastguard Worker using verifier::VerifierDeps;
32*795d594fSAndroid Build Coastguard Worker 
33*795d594fSAndroid Build Coastguard Worker class Dex2oatVdexTest : public Dex2oatEnvironmentTest {
34*795d594fSAndroid Build Coastguard Worker  public:
TearDown()35*795d594fSAndroid Build Coastguard Worker   void TearDown() override {
36*795d594fSAndroid Build Coastguard Worker     Dex2oatEnvironmentTest::TearDown();
37*795d594fSAndroid Build Coastguard Worker 
38*795d594fSAndroid Build Coastguard Worker     output_ = "";
39*795d594fSAndroid Build Coastguard Worker     opened_vdex_files_.clear();
40*795d594fSAndroid Build Coastguard Worker   }
41*795d594fSAndroid Build Coastguard Worker 
42*795d594fSAndroid Build Coastguard Worker  protected:
RunDex2oat(const std::string & dex_location,const std::string & odex_location,const std::string * public_sdk,bool copy_dex_files=false,const std::vector<std::string> & extra_args={})43*795d594fSAndroid Build Coastguard Worker   Result<bool> RunDex2oat(const std::string& dex_location,
44*795d594fSAndroid Build Coastguard Worker                           const std::string& odex_location,
45*795d594fSAndroid Build Coastguard Worker                           const std::string* public_sdk,
46*795d594fSAndroid Build Coastguard Worker                           bool copy_dex_files = false,
47*795d594fSAndroid Build Coastguard Worker                           const std::vector<std::string>& extra_args = {}) {
48*795d594fSAndroid Build Coastguard Worker     std::vector<std::string> args;
49*795d594fSAndroid Build Coastguard Worker     args.push_back("--dex-file=" + dex_location);
50*795d594fSAndroid Build Coastguard Worker     args.push_back("--oat-file=" + odex_location);
51*795d594fSAndroid Build Coastguard Worker     if (public_sdk != nullptr) {
52*795d594fSAndroid Build Coastguard Worker       args.push_back("--public-sdk=" + *public_sdk);
53*795d594fSAndroid Build Coastguard Worker     }
54*795d594fSAndroid Build Coastguard Worker     args.push_back("--compiler-filter=" +
55*795d594fSAndroid Build Coastguard Worker                    CompilerFilter::NameOfFilter(CompilerFilter::Filter::kVerify));
56*795d594fSAndroid Build Coastguard Worker     args.push_back("--runtime-arg");
57*795d594fSAndroid Build Coastguard Worker     args.push_back("-Xnorelocate");
58*795d594fSAndroid Build Coastguard Worker     if (!copy_dex_files) {
59*795d594fSAndroid Build Coastguard Worker       args.push_back("--copy-dex-files=false");
60*795d594fSAndroid Build Coastguard Worker     }
61*795d594fSAndroid Build Coastguard Worker     args.push_back("--runtime-arg");
62*795d594fSAndroid Build Coastguard Worker     args.push_back("-verbose:verifier,compiler");
63*795d594fSAndroid Build Coastguard Worker     // Use a single thread to facilitate debugging. We only compile tiny dex files.
64*795d594fSAndroid Build Coastguard Worker     args.push_back("-j1");
65*795d594fSAndroid Build Coastguard Worker 
66*795d594fSAndroid Build Coastguard Worker     args.insert(args.end(), extra_args.begin(), extra_args.end());
67*795d594fSAndroid Build Coastguard Worker 
68*795d594fSAndroid Build Coastguard Worker     int status = OR_RETURN(Dex2Oat(args, &output_));
69*795d594fSAndroid Build Coastguard Worker     return status == 0;
70*795d594fSAndroid Build Coastguard Worker   }
71*795d594fSAndroid Build Coastguard Worker 
GetVerifierDeps(const std::string & vdex_location,const DexFile * dex_file)72*795d594fSAndroid Build Coastguard Worker   Result<std::unique_ptr<VerifierDeps>> GetVerifierDeps(const std::string& vdex_location,
73*795d594fSAndroid Build Coastguard Worker                                                         const DexFile* dex_file) {
74*795d594fSAndroid Build Coastguard Worker     // Verify the vdex file content: only the classes using public APIs should be verified.
75*795d594fSAndroid Build Coastguard Worker     std::string error_msg;
76*795d594fSAndroid Build Coastguard Worker     std::unique_ptr<VdexFile> vdex(VdexFile::Open(vdex_location,
77*795d594fSAndroid Build Coastguard Worker                                                   /*writable=*/false,
78*795d594fSAndroid Build Coastguard Worker                                                   /*low_4gb=*/false,
79*795d594fSAndroid Build Coastguard Worker                                                   &error_msg));
80*795d594fSAndroid Build Coastguard Worker     // Check the vdex doesn't have dex.
81*795d594fSAndroid Build Coastguard Worker     if (vdex->HasDexSection()) {
82*795d594fSAndroid Build Coastguard Worker       return Errorf("The vdex {} should not contain dex code", vdex_location);
83*795d594fSAndroid Build Coastguard Worker     }
84*795d594fSAndroid Build Coastguard Worker 
85*795d594fSAndroid Build Coastguard Worker     // Verify the deps.
86*795d594fSAndroid Build Coastguard Worker     VdexFile::VdexFileHeader vdex_header = vdex->GetVdexFileHeader();
87*795d594fSAndroid Build Coastguard Worker     if (!vdex_header.IsValid()) {
88*795d594fSAndroid Build Coastguard Worker       return Errorf("Invalid vdex header in {}", vdex_location);
89*795d594fSAndroid Build Coastguard Worker     }
90*795d594fSAndroid Build Coastguard Worker 
91*795d594fSAndroid Build Coastguard Worker     std::vector<const DexFile*> dex_files;
92*795d594fSAndroid Build Coastguard Worker     dex_files.push_back(dex_file);
93*795d594fSAndroid Build Coastguard Worker     std::unique_ptr<VerifierDeps> deps(new VerifierDeps(dex_files, /*output_only=*/false));
94*795d594fSAndroid Build Coastguard Worker 
95*795d594fSAndroid Build Coastguard Worker     if (!deps->ParseStoredData(dex_files, vdex->GetVerifierDepsData())) {
96*795d594fSAndroid Build Coastguard Worker       return Errorf("{}", error_msg);
97*795d594fSAndroid Build Coastguard Worker     }
98*795d594fSAndroid Build Coastguard Worker 
99*795d594fSAndroid Build Coastguard Worker     opened_vdex_files_.push_back(std::move(vdex));
100*795d594fSAndroid Build Coastguard Worker     return deps;
101*795d594fSAndroid Build Coastguard Worker   }
102*795d594fSAndroid Build Coastguard Worker 
GetClassDefIndex(const std::string & cls,const DexFile & dex_file)103*795d594fSAndroid Build Coastguard Worker   uint16_t GetClassDefIndex(const std::string& cls, const DexFile& dex_file) {
104*795d594fSAndroid Build Coastguard Worker     const dex::TypeId* type_id = dex_file.FindTypeId(cls.c_str());
105*795d594fSAndroid Build Coastguard Worker     DCHECK(type_id != nullptr);
106*795d594fSAndroid Build Coastguard Worker     dex::TypeIndex type_idx = dex_file.GetIndexForTypeId(*type_id);
107*795d594fSAndroid Build Coastguard Worker     const dex::ClassDef* class_def = dex_file.FindClassDef(type_idx);
108*795d594fSAndroid Build Coastguard Worker     DCHECK(class_def != nullptr);
109*795d594fSAndroid Build Coastguard Worker     return dex_file.GetIndexForClassDef(*class_def);
110*795d594fSAndroid Build Coastguard Worker   }
111*795d594fSAndroid Build Coastguard Worker 
HasVerifiedClass(const std::unique_ptr<VerifierDeps> & deps,const std::string & cls,const DexFile & dex_file)112*795d594fSAndroid Build Coastguard Worker   bool HasVerifiedClass(const std::unique_ptr<VerifierDeps>& deps,
113*795d594fSAndroid Build Coastguard Worker                         const std::string& cls,
114*795d594fSAndroid Build Coastguard Worker                         const DexFile& dex_file) {
115*795d594fSAndroid Build Coastguard Worker     uint16_t class_def_idx = GetClassDefIndex(cls, dex_file);
116*795d594fSAndroid Build Coastguard Worker     return deps->GetVerifiedClasses(dex_file)[class_def_idx];
117*795d594fSAndroid Build Coastguard Worker   }
118*795d594fSAndroid Build Coastguard Worker 
GetFilename(const std::unique_ptr<const DexFile> & dex_file)119*795d594fSAndroid Build Coastguard Worker   std::string GetFilename(const std::unique_ptr<const DexFile>& dex_file) {
120*795d594fSAndroid Build Coastguard Worker     const std::string& str = dex_file->GetLocation();
121*795d594fSAndroid Build Coastguard Worker     size_t idx = str.rfind('/');
122*795d594fSAndroid Build Coastguard Worker     if (idx == std::string::npos) {
123*795d594fSAndroid Build Coastguard Worker       return str;
124*795d594fSAndroid Build Coastguard Worker     }
125*795d594fSAndroid Build Coastguard Worker     return str.substr(idx + 1);
126*795d594fSAndroid Build Coastguard Worker   }
127*795d594fSAndroid Build Coastguard Worker 
GetOdex(const std::unique_ptr<const DexFile> & dex_file,const std::string & suffix="")128*795d594fSAndroid Build Coastguard Worker   std::string GetOdex(const std::unique_ptr<const DexFile>& dex_file,
129*795d594fSAndroid Build Coastguard Worker                       const std::string& suffix = "") {
130*795d594fSAndroid Build Coastguard Worker     return GetScratchDir() + "/" + GetFilename(dex_file) + suffix + ".odex";
131*795d594fSAndroid Build Coastguard Worker   }
132*795d594fSAndroid Build Coastguard Worker 
GetVdex(const std::unique_ptr<const DexFile> & dex_file,const std::string & suffix="")133*795d594fSAndroid Build Coastguard Worker   std::string GetVdex(const std::unique_ptr<const DexFile>& dex_file,
134*795d594fSAndroid Build Coastguard Worker                       const std::string& suffix = "") {
135*795d594fSAndroid Build Coastguard Worker     return GetScratchDir() + "/" + GetFilename(dex_file) + suffix + ".vdex";
136*795d594fSAndroid Build Coastguard Worker   }
137*795d594fSAndroid Build Coastguard Worker 
138*795d594fSAndroid Build Coastguard Worker   std::string output_;
139*795d594fSAndroid Build Coastguard Worker   std::vector<std::unique_ptr<VdexFile>> opened_vdex_files_;
140*795d594fSAndroid Build Coastguard Worker };
141*795d594fSAndroid Build Coastguard Worker 
142*795d594fSAndroid Build Coastguard Worker // Validates verification against public API stubs:
143*795d594fSAndroid Build Coastguard Worker // - create a vdex file contraints by a predefined list of public API (passed as separate dex)
144*795d594fSAndroid Build Coastguard Worker // - compile with the above vdex file as input to validate the compilation flow
TEST_F(Dex2oatVdexTest,VerifyPublicSdkStubs)145*795d594fSAndroid Build Coastguard Worker TEST_F(Dex2oatVdexTest, VerifyPublicSdkStubs) {
146*795d594fSAndroid Build Coastguard Worker   // Dex2oatVdexTestDex is the subject app using normal APIs found in the boot classpath.
147*795d594fSAndroid Build Coastguard Worker   std::unique_ptr<const DexFile> dex_file(OpenTestDexFile("Dex2oatVdexTestDex"));
148*795d594fSAndroid Build Coastguard Worker   // Dex2oatVdexPublicSdkDex serves as the public API-stubs, restricting what can be verified.
149*795d594fSAndroid Build Coastguard Worker   const std::string api_dex_location = GetTestDexFileName("Dex2oatVdexPublicSdkDex");
150*795d594fSAndroid Build Coastguard Worker 
151*795d594fSAndroid Build Coastguard Worker   // Compile the subject app using the predefined API-stubs
152*795d594fSAndroid Build Coastguard Worker   ASSERT_THAT(RunDex2oat(dex_file->GetLocation(), GetOdex(dex_file), &api_dex_location),
153*795d594fSAndroid Build Coastguard Worker               HasValue(true));
154*795d594fSAndroid Build Coastguard Worker 
155*795d594fSAndroid Build Coastguard Worker   std::unique_ptr<VerifierDeps> deps =
156*795d594fSAndroid Build Coastguard Worker       OR_ASSERT_FAIL(GetVerifierDeps(GetVdex(dex_file), dex_file.get()));
157*795d594fSAndroid Build Coastguard Worker 
158*795d594fSAndroid Build Coastguard Worker   // Verify public API usage. The classes should be verified.
159*795d594fSAndroid Build Coastguard Worker   ASSERT_TRUE(HasVerifiedClass(deps, "LAccessPublicCtor;", *dex_file));
160*795d594fSAndroid Build Coastguard Worker   ASSERT_TRUE(HasVerifiedClass(deps, "LAccessPublicMethod;", *dex_file));
161*795d594fSAndroid Build Coastguard Worker   ASSERT_TRUE(HasVerifiedClass(deps, "LAccessPublicMethodFromParent;", *dex_file));
162*795d594fSAndroid Build Coastguard Worker   ASSERT_TRUE(HasVerifiedClass(deps, "LAccessPublicStaticMethod;", *dex_file));
163*795d594fSAndroid Build Coastguard Worker   ASSERT_TRUE(HasVerifiedClass(deps, "LAccessPublicStaticField;", *dex_file));
164*795d594fSAndroid Build Coastguard Worker 
165*795d594fSAndroid Build Coastguard Worker   // Verify NON public API usage. The classes should be verified, but will run
166*795d594fSAndroid Build Coastguard Worker   // with access checks.
167*795d594fSAndroid Build Coastguard Worker   ASSERT_TRUE(HasVerifiedClass(deps, "LAccessNonPublicCtor;", *dex_file));
168*795d594fSAndroid Build Coastguard Worker   ASSERT_TRUE(HasVerifiedClass(deps, "LAccessNonPublicMethod;", *dex_file));
169*795d594fSAndroid Build Coastguard Worker   ASSERT_TRUE(HasVerifiedClass(deps, "LAccessNonPublicMethodFromParent;", *dex_file));
170*795d594fSAndroid Build Coastguard Worker   ASSERT_TRUE(HasVerifiedClass(deps, "LAccessNonPublicStaticMethod;", *dex_file));
171*795d594fSAndroid Build Coastguard Worker   ASSERT_TRUE(HasVerifiedClass(deps, "LAccessNonPublicStaticField;", *dex_file));
172*795d594fSAndroid Build Coastguard Worker 
173*795d594fSAndroid Build Coastguard Worker   // Compile again without public API stubs but with the previously generated vdex.
174*795d594fSAndroid Build Coastguard Worker   // This simulates a normal install where the apk has its code pre-verified.
175*795d594fSAndroid Build Coastguard Worker   // The results should be the same.
176*795d594fSAndroid Build Coastguard Worker 
177*795d594fSAndroid Build Coastguard Worker   std::string dm_file = GetScratchDir() + "/base.dm";
178*795d594fSAndroid Build Coastguard Worker   CreateDexMetadata(GetVdex(dex_file), dm_file);
179*795d594fSAndroid Build Coastguard Worker   std::vector<std::string> extra_args;
180*795d594fSAndroid Build Coastguard Worker   extra_args.push_back("--dm-file=" + dm_file);
181*795d594fSAndroid Build Coastguard Worker   output_ = "";
182*795d594fSAndroid Build Coastguard Worker   ASSERT_THAT(RunDex2oat(dex_file->GetLocation(), GetOdex(dex_file), nullptr, false, extra_args),
183*795d594fSAndroid Build Coastguard Worker               HasValue(true));
184*795d594fSAndroid Build Coastguard Worker 
185*795d594fSAndroid Build Coastguard Worker   std::unique_ptr<VerifierDeps> deps2 =
186*795d594fSAndroid Build Coastguard Worker       OR_ASSERT_FAIL(GetVerifierDeps(GetVdex(dex_file), dex_file.get()));
187*795d594fSAndroid Build Coastguard Worker 
188*795d594fSAndroid Build Coastguard Worker   ASSERT_TRUE(HasVerifiedClass(deps2, "LAccessPublicCtor;", *dex_file));
189*795d594fSAndroid Build Coastguard Worker   ASSERT_TRUE(HasVerifiedClass(deps2, "LAccessPublicMethod;", *dex_file));
190*795d594fSAndroid Build Coastguard Worker   ASSERT_TRUE(HasVerifiedClass(deps2, "LAccessPublicMethodFromParent;", *dex_file));
191*795d594fSAndroid Build Coastguard Worker   ASSERT_TRUE(HasVerifiedClass(deps2, "LAccessPublicStaticMethod;", *dex_file));
192*795d594fSAndroid Build Coastguard Worker   ASSERT_TRUE(HasVerifiedClass(deps2, "LAccessPublicStaticField;", *dex_file));
193*795d594fSAndroid Build Coastguard Worker 
194*795d594fSAndroid Build Coastguard Worker   ASSERT_TRUE(HasVerifiedClass(deps2, "LAccessNonPublicCtor;", *dex_file)) << output_;
195*795d594fSAndroid Build Coastguard Worker   ASSERT_TRUE(HasVerifiedClass(deps2, "LAccessNonPublicMethod;", *dex_file));
196*795d594fSAndroid Build Coastguard Worker   ASSERT_TRUE(HasVerifiedClass(deps2, "LAccessNonPublicMethodFromParent;", *dex_file));
197*795d594fSAndroid Build Coastguard Worker   ASSERT_TRUE(HasVerifiedClass(deps2, "LAccessNonPublicStaticMethod;", *dex_file));
198*795d594fSAndroid Build Coastguard Worker   ASSERT_TRUE(HasVerifiedClass(deps2, "LAccessNonPublicStaticField;", *dex_file));
199*795d594fSAndroid Build Coastguard Worker }
200*795d594fSAndroid Build Coastguard Worker 
201*795d594fSAndroid Build Coastguard Worker // Check that if the input dm does contain dex files then the compilation fails
TEST_F(Dex2oatVdexTest,VerifyPublicSdkStubsWithDexFiles)202*795d594fSAndroid Build Coastguard Worker TEST_F(Dex2oatVdexTest, VerifyPublicSdkStubsWithDexFiles) {
203*795d594fSAndroid Build Coastguard Worker   // Dex2oatVdexTestDex is the subject app using normal APIs found in the boot classpath.
204*795d594fSAndroid Build Coastguard Worker   std::unique_ptr<const DexFile> dex_file(OpenTestDexFile("Dex2oatVdexTestDex"));
205*795d594fSAndroid Build Coastguard Worker 
206*795d594fSAndroid Build Coastguard Worker   // Compile the subject app using the predefined API-stubs
207*795d594fSAndroid Build Coastguard Worker   ASSERT_THAT(RunDex2oat(dex_file->GetLocation(),
208*795d594fSAndroid Build Coastguard Worker                          GetOdex(dex_file),
209*795d594fSAndroid Build Coastguard Worker                          /*public_sdk=*/nullptr,
210*795d594fSAndroid Build Coastguard Worker                          /*copy_dex_files=*/true),
211*795d594fSAndroid Build Coastguard Worker               HasValue(true));
212*795d594fSAndroid Build Coastguard Worker 
213*795d594fSAndroid Build Coastguard Worker   // Create the .dm file with the output.
214*795d594fSAndroid Build Coastguard Worker   std::string dm_file = GetScratchDir() + "/base.dm";
215*795d594fSAndroid Build Coastguard Worker   CreateDexMetadata(GetVdex(dex_file), dm_file);
216*795d594fSAndroid Build Coastguard Worker   std::vector<std::string> extra_args;
217*795d594fSAndroid Build Coastguard Worker   extra_args.push_back("--dm-file=" + dm_file);
218*795d594fSAndroid Build Coastguard Worker 
219*795d594fSAndroid Build Coastguard Worker   // Recompile again with the .dm file which contains a vdex with code.
220*795d594fSAndroid Build Coastguard Worker   // The compilation will pass, but dex2oat will not use the vdex file.
221*795d594fSAndroid Build Coastguard Worker   ASSERT_THAT(RunDex2oat(dex_file->GetLocation(),
222*795d594fSAndroid Build Coastguard Worker                          GetOdex(dex_file, "v2"),
223*795d594fSAndroid Build Coastguard Worker                          /*public_sdk=*/nullptr,
224*795d594fSAndroid Build Coastguard Worker                          /*copy_dex_files=*/true,
225*795d594fSAndroid Build Coastguard Worker                          extra_args),
226*795d594fSAndroid Build Coastguard Worker               HasValue(true));
227*795d594fSAndroid Build Coastguard Worker }
228*795d594fSAndroid Build Coastguard Worker 
229*795d594fSAndroid Build Coastguard Worker // Check that corrupt vdex files from .dm archives are ignored.
TEST_F(Dex2oatVdexTest,VerifyCorruptVdexFile)230*795d594fSAndroid Build Coastguard Worker TEST_F(Dex2oatVdexTest, VerifyCorruptVdexFile) {
231*795d594fSAndroid Build Coastguard Worker   // Dex2oatVdexTestDex is the subject app using normal APIs found in the boot classpath.
232*795d594fSAndroid Build Coastguard Worker   std::unique_ptr<const DexFile> dex_file(OpenTestDexFile("Dex2oatVdexTestDex"));
233*795d594fSAndroid Build Coastguard Worker 
234*795d594fSAndroid Build Coastguard Worker   // Create the .dm file with the output.
235*795d594fSAndroid Build Coastguard Worker   // Instead passing the vdex files, pass the actual dex file. This will simulate a vdex corruption.
236*795d594fSAndroid Build Coastguard Worker   // The compiler should ignore it.
237*795d594fSAndroid Build Coastguard Worker   std::string dm_file = GetScratchDir() + "/base.dm";
238*795d594fSAndroid Build Coastguard Worker   CreateDexMetadata(dex_file->GetLocation(), dm_file);
239*795d594fSAndroid Build Coastguard Worker   std::vector<std::string> extra_args;
240*795d594fSAndroid Build Coastguard Worker   extra_args.push_back("--dm-file=" + dm_file);
241*795d594fSAndroid Build Coastguard Worker 
242*795d594fSAndroid Build Coastguard Worker   // Compile the dex file. Despite having a corrupt input .vdex, we should not crash.
243*795d594fSAndroid Build Coastguard Worker   ASSERT_THAT(RunDex2oat(dex_file->GetLocation(),
244*795d594fSAndroid Build Coastguard Worker                          GetOdex(dex_file),
245*795d594fSAndroid Build Coastguard Worker                          /*public_sdk=*/nullptr,
246*795d594fSAndroid Build Coastguard Worker                          /*copy_dex_files=*/true,
247*795d594fSAndroid Build Coastguard Worker                          extra_args),
248*795d594fSAndroid Build Coastguard Worker               HasValue(true))
249*795d594fSAndroid Build Coastguard Worker       << output_;
250*795d594fSAndroid Build Coastguard Worker }
251*795d594fSAndroid Build Coastguard Worker 
252*795d594fSAndroid Build Coastguard Worker // Check that if the input dm a vdex with mismatching checksums the compilation fails
TEST_F(Dex2oatVdexTest,VerifyInputDmWithMismatchedChecksums)253*795d594fSAndroid Build Coastguard Worker TEST_F(Dex2oatVdexTest, VerifyInputDmWithMismatchedChecksums) {
254*795d594fSAndroid Build Coastguard Worker   // Generate a vdex file for Dex2oatVdexTestDex.
255*795d594fSAndroid Build Coastguard Worker   std::unique_ptr<const DexFile> dex_file(OpenTestDexFile("Dex2oatVdexTestDex"));
256*795d594fSAndroid Build Coastguard Worker 
257*795d594fSAndroid Build Coastguard Worker   ASSERT_THAT(RunDex2oat(dex_file->GetLocation(),
258*795d594fSAndroid Build Coastguard Worker                          GetOdex(dex_file),
259*795d594fSAndroid Build Coastguard Worker                          /*public_sdk=*/nullptr,
260*795d594fSAndroid Build Coastguard Worker                          /*copy_dex_files=*/false),
261*795d594fSAndroid Build Coastguard Worker               HasValue(true));
262*795d594fSAndroid Build Coastguard Worker 
263*795d594fSAndroid Build Coastguard Worker   // Create the .dm file with the output.
264*795d594fSAndroid Build Coastguard Worker   std::string dm_file = GetScratchDir() + "/base.dm";
265*795d594fSAndroid Build Coastguard Worker   CreateDexMetadata(GetVdex(dex_file), dm_file);
266*795d594fSAndroid Build Coastguard Worker   std::vector<std::string> extra_args;
267*795d594fSAndroid Build Coastguard Worker   extra_args.push_back("--dm-file=" + dm_file);
268*795d594fSAndroid Build Coastguard Worker 
269*795d594fSAndroid Build Coastguard Worker   // Try to compile Main using an input dm which contains the vdex for
270*795d594fSAndroid Build Coastguard Worker   // Dex2oatVdexTestDex. It should fail.
271*795d594fSAndroid Build Coastguard Worker   std::unique_ptr<const DexFile> dex_file2(OpenTestDexFile("Main"));
272*795d594fSAndroid Build Coastguard Worker   ASSERT_THAT(RunDex2oat(dex_file2->GetLocation(),
273*795d594fSAndroid Build Coastguard Worker                          GetOdex(dex_file2, "v2"),
274*795d594fSAndroid Build Coastguard Worker                          /*public_sdk=*/nullptr,
275*795d594fSAndroid Build Coastguard Worker                          /*copy_dex_files=*/false,
276*795d594fSAndroid Build Coastguard Worker                          extra_args),
277*795d594fSAndroid Build Coastguard Worker               HasValue(false))
278*795d594fSAndroid Build Coastguard Worker       << output_;
279*795d594fSAndroid Build Coastguard Worker }
280*795d594fSAndroid Build Coastguard Worker 
281*795d594fSAndroid Build Coastguard Worker }  // namespace art
282