184f50aecdeed2d9ed3206681820e41ad6af73a9cRichard Uhler/*
284f50aecdeed2d9ed3206681820e41ad6af73a9cRichard Uhler * Copyright (C) 2017 The Android Open Source Project
384f50aecdeed2d9ed3206681820e41ad6af73a9cRichard Uhler *
484f50aecdeed2d9ed3206681820e41ad6af73a9cRichard Uhler * Licensed under the Apache License, Version 2.0 (the "License");
584f50aecdeed2d9ed3206681820e41ad6af73a9cRichard Uhler * you may not use this file except in compliance with the License.
684f50aecdeed2d9ed3206681820e41ad6af73a9cRichard Uhler * You may obtain a copy of the License at
784f50aecdeed2d9ed3206681820e41ad6af73a9cRichard Uhler *
884f50aecdeed2d9ed3206681820e41ad6af73a9cRichard Uhler *      http://www.apache.org/licenses/LICENSE-2.0
984f50aecdeed2d9ed3206681820e41ad6af73a9cRichard Uhler *
1084f50aecdeed2d9ed3206681820e41ad6af73a9cRichard Uhler * Unless required by applicable law or agreed to in writing, software
1184f50aecdeed2d9ed3206681820e41ad6af73a9cRichard Uhler * distributed under the License is distributed on an "AS IS" BASIS,
1284f50aecdeed2d9ed3206681820e41ad6af73a9cRichard Uhler * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1384f50aecdeed2d9ed3206681820e41ad6af73a9cRichard Uhler * See the License for the specific language governing permissions and
1484f50aecdeed2d9ed3206681820e41ad6af73a9cRichard Uhler * limitations under the License.
1584f50aecdeed2d9ed3206681820e41ad6af73a9cRichard Uhler */
1684f50aecdeed2d9ed3206681820e41ad6af73a9cRichard Uhler
1784f50aecdeed2d9ed3206681820e41ad6af73a9cRichard Uhler#include <gtest/gtest.h>
1884f50aecdeed2d9ed3206681820e41ad6af73a9cRichard Uhler
19178c880f7ec15d9ebbfdbcefb3b12c5cbdb2cc60Andreas Gampe#include "android-base/stringprintf.h"
20178c880f7ec15d9ebbfdbcefb3b12c5cbdb2cc60Andreas Gampe
2184f50aecdeed2d9ed3206681820e41ad6af73a9cRichard Uhler#include "dexopt_test.h"
22178c880f7ec15d9ebbfdbcefb3b12c5cbdb2cc60Andreas Gampe#include "noop_compiler_callbacks.h"
2384f50aecdeed2d9ed3206681820e41ad6af73a9cRichard Uhler
2484f50aecdeed2d9ed3206681820e41ad6af73a9cRichard Uhlernamespace art {
2584f50aecdeed2d9ed3206681820e41ad6af73a9cRichard Uhlernamespace gc {
2684f50aecdeed2d9ed3206681820e41ad6af73a9cRichard Uhlernamespace space {
2784f50aecdeed2d9ed3206681820e41ad6af73a9cRichard Uhler
2884f50aecdeed2d9ed3206681820e41ad6af73a9cRichard UhlerTEST_F(DexoptTest, ValidateOatFile) {
2984f50aecdeed2d9ed3206681820e41ad6af73a9cRichard Uhler  std::string dex1 = GetScratchDir() + "/Dex1.jar";
3084f50aecdeed2d9ed3206681820e41ad6af73a9cRichard Uhler  std::string multidex1 = GetScratchDir() + "/MultiDex1.jar";
3184f50aecdeed2d9ed3206681820e41ad6af73a9cRichard Uhler  std::string dex2 = GetScratchDir() + "/Dex2.jar";
3284f50aecdeed2d9ed3206681820e41ad6af73a9cRichard Uhler  std::string oat_location = GetScratchDir() + "/Oat.oat";
3384f50aecdeed2d9ed3206681820e41ad6af73a9cRichard Uhler
3484f50aecdeed2d9ed3206681820e41ad6af73a9cRichard Uhler  Copy(GetDexSrc1(), dex1);
3584f50aecdeed2d9ed3206681820e41ad6af73a9cRichard Uhler  Copy(GetMultiDexSrc1(), multidex1);
3684f50aecdeed2d9ed3206681820e41ad6af73a9cRichard Uhler  Copy(GetDexSrc2(), dex2);
3784f50aecdeed2d9ed3206681820e41ad6af73a9cRichard Uhler
3884f50aecdeed2d9ed3206681820e41ad6af73a9cRichard Uhler  std::string error_msg;
3984f50aecdeed2d9ed3206681820e41ad6af73a9cRichard Uhler  std::vector<std::string> args;
4084f50aecdeed2d9ed3206681820e41ad6af73a9cRichard Uhler  args.push_back("--dex-file=" + dex1);
4184f50aecdeed2d9ed3206681820e41ad6af73a9cRichard Uhler  args.push_back("--dex-file=" + multidex1);
4284f50aecdeed2d9ed3206681820e41ad6af73a9cRichard Uhler  args.push_back("--dex-file=" + dex2);
4384f50aecdeed2d9ed3206681820e41ad6af73a9cRichard Uhler  args.push_back("--oat-file=" + oat_location);
4484f50aecdeed2d9ed3206681820e41ad6af73a9cRichard Uhler  ASSERT_TRUE(OatFileAssistant::Dex2Oat(args, &error_msg)) << error_msg;
4584f50aecdeed2d9ed3206681820e41ad6af73a9cRichard Uhler
4696dca1c979325cdd8d543982ced4ad4fd01994d7Nicolas Geoffray  std::unique_ptr<OatFile> oat(OatFile::Open(/* zip_fd */ -1,
4796dca1c979325cdd8d543982ced4ad4fd01994d7Nicolas Geoffray                                             oat_location.c_str(),
4884f50aecdeed2d9ed3206681820e41ad6af73a9cRichard Uhler                                             oat_location.c_str(),
4984f50aecdeed2d9ed3206681820e41ad6af73a9cRichard Uhler                                             nullptr,
5084f50aecdeed2d9ed3206681820e41ad6af73a9cRichard Uhler                                             nullptr,
5184f50aecdeed2d9ed3206681820e41ad6af73a9cRichard Uhler                                             false,
5284f50aecdeed2d9ed3206681820e41ad6af73a9cRichard Uhler                                             /*low_4gb*/false,
5384f50aecdeed2d9ed3206681820e41ad6af73a9cRichard Uhler                                             nullptr,
5484f50aecdeed2d9ed3206681820e41ad6af73a9cRichard Uhler                                             &error_msg));
5584f50aecdeed2d9ed3206681820e41ad6af73a9cRichard Uhler  ASSERT_TRUE(oat != nullptr) << error_msg;
5684f50aecdeed2d9ed3206681820e41ad6af73a9cRichard Uhler
5784f50aecdeed2d9ed3206681820e41ad6af73a9cRichard Uhler  // Originally all the dex checksums should be up to date.
5884f50aecdeed2d9ed3206681820e41ad6af73a9cRichard Uhler  EXPECT_TRUE(ImageSpace::ValidateOatFile(*oat, &error_msg)) << error_msg;
5984f50aecdeed2d9ed3206681820e41ad6af73a9cRichard Uhler
6084f50aecdeed2d9ed3206681820e41ad6af73a9cRichard Uhler  // Invalidate the dex1 checksum.
6184f50aecdeed2d9ed3206681820e41ad6af73a9cRichard Uhler  Copy(GetDexSrc2(), dex1);
6284f50aecdeed2d9ed3206681820e41ad6af73a9cRichard Uhler  EXPECT_FALSE(ImageSpace::ValidateOatFile(*oat, &error_msg));
6384f50aecdeed2d9ed3206681820e41ad6af73a9cRichard Uhler
6484f50aecdeed2d9ed3206681820e41ad6af73a9cRichard Uhler  // Restore the dex1 checksum.
6584f50aecdeed2d9ed3206681820e41ad6af73a9cRichard Uhler  Copy(GetDexSrc1(), dex1);
6684f50aecdeed2d9ed3206681820e41ad6af73a9cRichard Uhler  EXPECT_TRUE(ImageSpace::ValidateOatFile(*oat, &error_msg)) << error_msg;
6784f50aecdeed2d9ed3206681820e41ad6af73a9cRichard Uhler
6884f50aecdeed2d9ed3206681820e41ad6af73a9cRichard Uhler  // Invalidate the non-main multidex checksum.
6984f50aecdeed2d9ed3206681820e41ad6af73a9cRichard Uhler  Copy(GetMultiDexSrc2(), multidex1);
7084f50aecdeed2d9ed3206681820e41ad6af73a9cRichard Uhler  EXPECT_FALSE(ImageSpace::ValidateOatFile(*oat, &error_msg));
7184f50aecdeed2d9ed3206681820e41ad6af73a9cRichard Uhler
7284f50aecdeed2d9ed3206681820e41ad6af73a9cRichard Uhler  // Restore the multidex checksum.
7384f50aecdeed2d9ed3206681820e41ad6af73a9cRichard Uhler  Copy(GetMultiDexSrc1(), multidex1);
7484f50aecdeed2d9ed3206681820e41ad6af73a9cRichard Uhler  EXPECT_TRUE(ImageSpace::ValidateOatFile(*oat, &error_msg)) << error_msg;
7584f50aecdeed2d9ed3206681820e41ad6af73a9cRichard Uhler
7684f50aecdeed2d9ed3206681820e41ad6af73a9cRichard Uhler  // Invalidate the dex2 checksum.
7784f50aecdeed2d9ed3206681820e41ad6af73a9cRichard Uhler  Copy(GetDexSrc1(), dex2);
7884f50aecdeed2d9ed3206681820e41ad6af73a9cRichard Uhler  EXPECT_FALSE(ImageSpace::ValidateOatFile(*oat, &error_msg));
7984f50aecdeed2d9ed3206681820e41ad6af73a9cRichard Uhler
8084f50aecdeed2d9ed3206681820e41ad6af73a9cRichard Uhler  // restore the dex2 checksum.
8184f50aecdeed2d9ed3206681820e41ad6af73a9cRichard Uhler  Copy(GetDexSrc2(), dex2);
8284f50aecdeed2d9ed3206681820e41ad6af73a9cRichard Uhler  EXPECT_TRUE(ImageSpace::ValidateOatFile(*oat, &error_msg)) << error_msg;
8384f50aecdeed2d9ed3206681820e41ad6af73a9cRichard Uhler
8484f50aecdeed2d9ed3206681820e41ad6af73a9cRichard Uhler  // Replace the multidex file with a non-multidex file.
8584f50aecdeed2d9ed3206681820e41ad6af73a9cRichard Uhler  Copy(GetDexSrc1(), multidex1);
8684f50aecdeed2d9ed3206681820e41ad6af73a9cRichard Uhler  EXPECT_FALSE(ImageSpace::ValidateOatFile(*oat, &error_msg));
8784f50aecdeed2d9ed3206681820e41ad6af73a9cRichard Uhler
8884f50aecdeed2d9ed3206681820e41ad6af73a9cRichard Uhler  // Restore the multidex file
8984f50aecdeed2d9ed3206681820e41ad6af73a9cRichard Uhler  Copy(GetMultiDexSrc1(), multidex1);
9084f50aecdeed2d9ed3206681820e41ad6af73a9cRichard Uhler  EXPECT_TRUE(ImageSpace::ValidateOatFile(*oat, &error_msg)) << error_msg;
9184f50aecdeed2d9ed3206681820e41ad6af73a9cRichard Uhler
9284f50aecdeed2d9ed3206681820e41ad6af73a9cRichard Uhler  // Replace dex1 with a multidex file.
9384f50aecdeed2d9ed3206681820e41ad6af73a9cRichard Uhler  Copy(GetMultiDexSrc1(), dex1);
9484f50aecdeed2d9ed3206681820e41ad6af73a9cRichard Uhler  EXPECT_FALSE(ImageSpace::ValidateOatFile(*oat, &error_msg));
9584f50aecdeed2d9ed3206681820e41ad6af73a9cRichard Uhler
9684f50aecdeed2d9ed3206681820e41ad6af73a9cRichard Uhler  // Restore the dex1 file.
9784f50aecdeed2d9ed3206681820e41ad6af73a9cRichard Uhler  Copy(GetDexSrc1(), dex1);
9884f50aecdeed2d9ed3206681820e41ad6af73a9cRichard Uhler  EXPECT_TRUE(ImageSpace::ValidateOatFile(*oat, &error_msg)) << error_msg;
9984f50aecdeed2d9ed3206681820e41ad6af73a9cRichard Uhler
10084f50aecdeed2d9ed3206681820e41ad6af73a9cRichard Uhler  // Remove the dex2 file.
10184f50aecdeed2d9ed3206681820e41ad6af73a9cRichard Uhler  EXPECT_EQ(0, unlink(dex2.c_str()));
10284f50aecdeed2d9ed3206681820e41ad6af73a9cRichard Uhler  EXPECT_FALSE(ImageSpace::ValidateOatFile(*oat, &error_msg));
10384f50aecdeed2d9ed3206681820e41ad6af73a9cRichard Uhler
10484f50aecdeed2d9ed3206681820e41ad6af73a9cRichard Uhler  // Restore the dex2 file.
10584f50aecdeed2d9ed3206681820e41ad6af73a9cRichard Uhler  Copy(GetDexSrc2(), dex2);
10684f50aecdeed2d9ed3206681820e41ad6af73a9cRichard Uhler  EXPECT_TRUE(ImageSpace::ValidateOatFile(*oat, &error_msg)) << error_msg;
10784f50aecdeed2d9ed3206681820e41ad6af73a9cRichard Uhler
10884f50aecdeed2d9ed3206681820e41ad6af73a9cRichard Uhler  // Remove the multidex file.
10984f50aecdeed2d9ed3206681820e41ad6af73a9cRichard Uhler  EXPECT_EQ(0, unlink(multidex1.c_str()));
11084f50aecdeed2d9ed3206681820e41ad6af73a9cRichard Uhler  EXPECT_FALSE(ImageSpace::ValidateOatFile(*oat, &error_msg));
11184f50aecdeed2d9ed3206681820e41ad6af73a9cRichard Uhler}
11284f50aecdeed2d9ed3206681820e41ad6af73a9cRichard Uhler
113178c880f7ec15d9ebbfdbcefb3b12c5cbdb2cc60Andreas Gampetemplate <bool kImage, bool kRelocate, bool kPatchoat, bool kImageDex2oat>
114178c880f7ec15d9ebbfdbcefb3b12c5cbdb2cc60Andreas Gampeclass ImageSpaceLoadingTest : public CommonRuntimeTest {
115178c880f7ec15d9ebbfdbcefb3b12c5cbdb2cc60Andreas Gampe protected:
116178c880f7ec15d9ebbfdbcefb3b12c5cbdb2cc60Andreas Gampe  void SetUpRuntimeOptions(RuntimeOptions* options) OVERRIDE {
117178c880f7ec15d9ebbfdbcefb3b12c5cbdb2cc60Andreas Gampe    if (kImage) {
118178c880f7ec15d9ebbfdbcefb3b12c5cbdb2cc60Andreas Gampe      options->emplace_back(android::base::StringPrintf("-Ximage:%s", GetCoreArtLocation().c_str()),
119178c880f7ec15d9ebbfdbcefb3b12c5cbdb2cc60Andreas Gampe                            nullptr);
120178c880f7ec15d9ebbfdbcefb3b12c5cbdb2cc60Andreas Gampe    }
121178c880f7ec15d9ebbfdbcefb3b12c5cbdb2cc60Andreas Gampe    options->emplace_back(kRelocate ? "-Xrelocate" : "-Xnorelocate", nullptr);
122178c880f7ec15d9ebbfdbcefb3b12c5cbdb2cc60Andreas Gampe    if (!kPatchoat) {
123178c880f7ec15d9ebbfdbcefb3b12c5cbdb2cc60Andreas Gampe      options->emplace_back("-Xpatchoat:false", nullptr);
124178c880f7ec15d9ebbfdbcefb3b12c5cbdb2cc60Andreas Gampe    }
125178c880f7ec15d9ebbfdbcefb3b12c5cbdb2cc60Andreas Gampe    options->emplace_back(kImageDex2oat ? "-Ximage-dex2oat" : "-Xnoimage-dex2oat", nullptr);
126178c880f7ec15d9ebbfdbcefb3b12c5cbdb2cc60Andreas Gampe
127178c880f7ec15d9ebbfdbcefb3b12c5cbdb2cc60Andreas Gampe    // We want to test the relocation behavior of ImageSpace. As such, don't pretend we're a
128178c880f7ec15d9ebbfdbcefb3b12c5cbdb2cc60Andreas Gampe    // compiler.
129178c880f7ec15d9ebbfdbcefb3b12c5cbdb2cc60Andreas Gampe    callbacks_.reset();
130178c880f7ec15d9ebbfdbcefb3b12c5cbdb2cc60Andreas Gampe  }
131178c880f7ec15d9ebbfdbcefb3b12c5cbdb2cc60Andreas Gampe};
132178c880f7ec15d9ebbfdbcefb3b12c5cbdb2cc60Andreas Gampe
133178c880f7ec15d9ebbfdbcefb3b12c5cbdb2cc60Andreas Gampeusing ImageSpacePatchoatTest = ImageSpaceLoadingTest<true, true, true, true>;
134178c880f7ec15d9ebbfdbcefb3b12c5cbdb2cc60Andreas GampeTEST_F(ImageSpacePatchoatTest, Test) {
135178c880f7ec15d9ebbfdbcefb3b12c5cbdb2cc60Andreas Gampe  EXPECT_FALSE(Runtime::Current()->GetHeap()->GetBootImageSpaces().empty());
136178c880f7ec15d9ebbfdbcefb3b12c5cbdb2cc60Andreas Gampe}
137178c880f7ec15d9ebbfdbcefb3b12c5cbdb2cc60Andreas Gampe
138178c880f7ec15d9ebbfdbcefb3b12c5cbdb2cc60Andreas Gampeusing ImageSpaceDex2oatTest = ImageSpaceLoadingTest<false, true, false, true>;
139178c880f7ec15d9ebbfdbcefb3b12c5cbdb2cc60Andreas GampeTEST_F(ImageSpaceDex2oatTest, Test) {
140178c880f7ec15d9ebbfdbcefb3b12c5cbdb2cc60Andreas Gampe  EXPECT_FALSE(Runtime::Current()->GetHeap()->GetBootImageSpaces().empty());
141178c880f7ec15d9ebbfdbcefb3b12c5cbdb2cc60Andreas Gampe}
142178c880f7ec15d9ebbfdbcefb3b12c5cbdb2cc60Andreas Gampe
14349086971304e00347af177d5a23350b8063ebaa4Vladimir Markousing ImageSpaceNoDex2oatNoPatchoatTest = ImageSpaceLoadingTest<true, true, false, false>;
14449086971304e00347af177d5a23350b8063ebaa4Vladimir MarkoTEST_F(ImageSpaceNoDex2oatNoPatchoatTest, Test) {
14549086971304e00347af177d5a23350b8063ebaa4Vladimir Marko  EXPECT_TRUE(Runtime::Current()->GetHeap()->GetBootImageSpaces().empty());
14649086971304e00347af177d5a23350b8063ebaa4Vladimir Marko}
147178c880f7ec15d9ebbfdbcefb3b12c5cbdb2cc60Andreas Gampe
148178c880f7ec15d9ebbfdbcefb3b12c5cbdb2cc60Andreas Gampeusing ImageSpaceNoRelocateNoDex2oatNoPatchoatTest = ImageSpaceLoadingTest<true, false, false, false>;
149178c880f7ec15d9ebbfdbcefb3b12c5cbdb2cc60Andreas GampeTEST_F(ImageSpaceNoRelocateNoDex2oatNoPatchoatTest, Test) {
150178c880f7ec15d9ebbfdbcefb3b12c5cbdb2cc60Andreas Gampe  EXPECT_FALSE(Runtime::Current()->GetHeap()->GetBootImageSpaces().empty());
151178c880f7ec15d9ebbfdbcefb3b12c5cbdb2cc60Andreas Gampe}
152178c880f7ec15d9ebbfdbcefb3b12c5cbdb2cc60Andreas Gampe
15384f50aecdeed2d9ed3206681820e41ad6af73a9cRichard Uhler}  // namespace space
15484f50aecdeed2d9ed3206681820e41ad6af73a9cRichard Uhler}  // namespace gc
15584f50aecdeed2d9ed3206681820e41ad6af73a9cRichard Uhler}  // namespace art
156